You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/05/10 14:40:44 UTC
[03/13] ignite git commit: IGNITE-5172 .NET: Fix type name parser and
resolver to handle arrays and simple names
IGNITE-5172 .NET: Fix type name parser and resolver to handle arrays and simple names
This closes #1909
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ba21c46c
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ba21c46c
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ba21c46c
Branch: refs/heads/ignite-5009
Commit: ba21c46cc15661d550e9018349ad266517446131
Parents: dddc6d4
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri May 5 18:38:29 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri May 5 18:38:29 2017 +0300
----------------------------------------------------------------------
.../Apache.Ignite.Core.Tests.csproj | 1 +
.../Binary/BinaryDynamicRegistrationTest.cs | 40 +++++++
.../Binary/BinaryNameMapperTest.cs | 7 ++
.../Binary/TypeNameParserTest.cs | 93 ++++++++++++---
.../Binary/TypeResolverTest.cs | 104 +++++++++++++++++
.../Cache/Query/CacheQueriesTest.cs | 5 +-
.../Apache.Ignite.Core.Tests/DeploymentTest.cs | 1 +
.../Examples/ExamplesTest.cs | 5 +-
.../Binary/BinaryBasicNameMapper.cs | 6 +-
.../Impl/Binary/BinaryProcessor.cs | 15 +--
.../Impl/Binary/BinaryReader.cs | 6 +-
.../Impl/Binary/Marshaller.cs | 18 ++-
.../Impl/Binary/TypeNameParser.cs | 31 ++++-
.../Impl/Binary/TypeResolver.cs | 115 +++++++++++++++----
.../Impl/Memory/PlatformMemoryStream.cs | 2 +-
15 files changed, 380 insertions(+), 69 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index c6b183b..7adbbbe 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@ -256,6 +256,7 @@
<ProjectReference Include="..\Examples\Apache.Ignite.ExamplesDll\Apache.Ignite.ExamplesDll.csproj">
<Project>{dfb08363-202e-412d-8812-349ef10a8702}</Project>
<Name>Apache.Ignite.ExamplesDll</Name>
+ <Aliases>ExamplesDll</Aliases>
</ProjectReference>
<ProjectReference Include="..\Examples\Apache.Ignite.Examples\Apache.Ignite.Examples.csproj">
<Project>{069fa680-3c4d-43a9-b84f-e67513b87827}</Project>
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs
index 549e453..927aa32 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs
@@ -18,6 +18,8 @@
// ReSharper disable UnusedAutoPropertyAccessor.Local
namespace Apache.Ignite.Core.Tests.Binary
{
+ extern alias ExamplesDll;
+
using System;
using System.Collections;
using System.Collections.Generic;
@@ -31,8 +33,11 @@ namespace Apache.Ignite.Core.Tests.Binary
using Apache.Ignite.Core.Impl.Binary;
using Apache.Ignite.Core.Impl.Common;
using Apache.Ignite.Core.Tests.Compute;
+ using Apache.Ignite.ExamplesDll.Binary;
using NUnit.Framework;
+ using ExamplesAccount = ExamplesDll::Apache.Ignite.ExamplesDll.Binary.Account;
+
/// <summary>
/// Tests the dynamic type registration.
/// </summary>
@@ -329,6 +334,28 @@ namespace Apache.Ignite.Core.Tests.Binary
}
/// <summary>
+ /// Tests that types with same FullName from different assemblies are mapped to each other.
+ /// </summary>
+ [Test]
+ public void TestSameTypeInDifferentAssemblies()
+ {
+ using (var ignite1 = Ignition.Start(TestUtils.GetTestConfiguration()))
+ {
+ var cache1 = ignite1.CreateCache<int, ExamplesAccount>("acc");
+ cache1[1] = new ExamplesAccount(1, 2.2m);
+
+ using (var ignite2 = Ignition.Start(TestUtils.GetTestConfiguration(name: "ignite2")))
+ {
+ var cache2 = ignite2.GetCache<int, Account>("acc");
+ cache2[2] = new Account {Id = 2, Balance = 3.3m};
+
+ Assert.AreEqual(1, cache2[1].Id); // Read ExamplesAccount as Account.
+ Assert.AreEqual(2, cache1[2].Id); // Read Account as ExamplesAccount.
+ }
+ }
+ }
+
+ /// <summary>
/// Tests the type registration.
/// </summary>
private static void Test(IIgnite ignite1, IIgnite ignite2)
@@ -492,3 +519,16 @@ namespace Apache.Ignite.Core.Tests.Binary
}
}
}
+
+namespace Apache.Ignite.ExamplesDll.Binary
+{
+ /// <summary>
+ /// Copy of Account class in ExamplesDll. Same name and namespace, different assembly.
+ /// </summary>
+ public class Account
+ {
+ public int Id { get; set; }
+
+ public decimal Balance { get; set; }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryNameMapperTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryNameMapperTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryNameMapperTest.cs
index b3ace97..ff1f91d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryNameMapperTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryNameMapperTest.cs
@@ -61,6 +61,13 @@ namespace Apache.Ignite.Core.Tests.Binary
Assert.AreEqual("Apache.Ignite.Core.Tests.Binary.BinaryNameMapperTest+Bar`1[[Apache.Ignite.Core.Tests." +
"Binary.BinaryNameMapperTest+Foo[]]][]",
mapper.GetTypeName(typeof(Bar<Foo[]>[]).AssemblyQualifiedName));
+
+ // Open generics.
+ Assert.AreEqual("System.Collections.Generic.List`1",
+ mapper.GetTypeName(typeof(List<>).AssemblyQualifiedName));
+
+ Assert.AreEqual("System.Collections.Generic.Dictionary`2",
+ mapper.GetTypeName(typeof(Dictionary<,>).AssemblyQualifiedName));
}
/// <summary>
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeNameParserTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeNameParserTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeNameParserTest.cs
index f3394a3..e566a4b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeNameParserTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeNameParserTest.cs
@@ -39,7 +39,7 @@ namespace Apache.Ignite.Core.Tests.Binary
{
// One letter.
var res = TypeNameParser.Parse("x");
- Assert.AreEqual("x", res.GetFullName());
+ Assert.AreEqual("x", res.GetNameWithNamespace());
Assert.AreEqual("x", res.GetName());
Assert.AreEqual(0, res.NameStart);
Assert.AreEqual(0, res.NameEnd);
@@ -79,78 +79,115 @@ namespace Apache.Ignite.Core.Tests.Binary
[Test]
public void TestGenericTypes()
{
- // Custom strings.
+ // Simple name.
var res = TypeNameParser.Parse("List`1[[Int]]");
Assert.AreEqual("List`1", res.GetName());
- Assert.AreEqual("List`1", res.GetFullName());
+ Assert.AreEqual("List`1", res.GetNameWithNamespace());
Assert.AreEqual("Int", res.Generics.Single().GetName());
- Assert.AreEqual("Int", res.Generics.Single().GetFullName());
+ Assert.AreEqual("Int", res.Generics.Single().GetNameWithNamespace());
+
+ // Simple name array.
+ res = TypeNameParser.Parse("List`1[[Byte[]]]");
+ Assert.AreEqual("List`1", res.GetName());
+ Assert.AreEqual("List`1", res.GetNameWithNamespace());
+ Assert.AreEqual("Byte", res.Generics.Single().GetName());
+ Assert.AreEqual("Byte", res.Generics.Single().GetNameWithNamespace());
+ Assert.AreEqual("[]", res.Generics.Single().GetArray());
+
+ // Simple name two-dimension array.
+ res = TypeNameParser.Parse("List`1[[Byte[,]]]");
+ Assert.AreEqual("List`1", res.GetName());
+ Assert.AreEqual("List`1", res.GetNameWithNamespace());
+ Assert.AreEqual("Byte", res.Generics.Single().GetName());
+ Assert.AreEqual("Byte", res.Generics.Single().GetNameWithNamespace());
+ Assert.AreEqual("[,]", res.Generics.Single().GetArray());
+
+ // Simple name jagged array.
+ res = TypeNameParser.Parse("List`1[[Byte[][]]]");
+ Assert.AreEqual("List`1", res.GetName());
+ Assert.AreEqual("List`1", res.GetNameWithNamespace());
+ Assert.AreEqual("Byte", res.Generics.Single().GetName());
+ Assert.AreEqual("Byte", res.Generics.Single().GetNameWithNamespace());
+ Assert.AreEqual("[][]", res.Generics.Single().GetArray());
+
+ // Open generic.
+ res = TypeNameParser.Parse("List`1");
+ Assert.AreEqual("List`1", res.GetName());
+ Assert.AreEqual("List`1", res.GetNameWithNamespace());
+ Assert.IsEmpty(res.Generics);
// One arg.
res = TypeNameParser.Parse(typeof(List<int>).AssemblyQualifiedName);
Assert.AreEqual("List`1", res.GetName());
- Assert.AreEqual("System.Collections.Generic.List`1", res.GetFullName());
+ Assert.AreEqual("System.Collections.Generic.List`1", res.GetNameWithNamespace());
Assert.IsTrue(res.GetAssemblyName().StartsWith("mscorlib,"));
Assert.AreEqual(1, res.Generics.Count);
var gen = res.Generics.Single();
Assert.AreEqual("Int32", gen.GetName());
- Assert.AreEqual("System.Int32", gen.GetFullName());
+ Assert.AreEqual("System.Int32", gen.GetNameWithNamespace());
Assert.IsTrue(gen.GetAssemblyName().StartsWith("mscorlib,"));
+ // One arg open.
+ res = TypeNameParser.Parse(typeof(List<>).AssemblyQualifiedName);
+ Assert.AreEqual("List`1", res.GetName());
+ Assert.AreEqual("System.Collections.Generic.List`1", res.GetNameWithNamespace());
+ Assert.IsTrue(res.GetAssemblyName().StartsWith("mscorlib,"));
+ Assert.IsEmpty(res.Generics);
+
// Two args.
res = TypeNameParser.Parse(typeof(Dictionary<int, string>).AssemblyQualifiedName);
Assert.AreEqual("Dictionary`2", res.GetName());
- Assert.AreEqual("System.Collections.Generic.Dictionary`2", res.GetFullName());
+ Assert.AreEqual("System.Collections.Generic.Dictionary`2", res.GetNameWithNamespace());
Assert.IsTrue(res.GetAssemblyName().StartsWith("mscorlib,"));
Assert.AreEqual(2, res.Generics.Count);
gen = res.Generics.First();
Assert.AreEqual("Int32", gen.GetName());
- Assert.AreEqual("System.Int32", gen.GetFullName());
+ Assert.AreEqual("System.Int32", gen.GetNameWithNamespace());
Assert.IsTrue(gen.GetAssemblyName().StartsWith("mscorlib,"));
gen = res.Generics.Last();
Assert.AreEqual("String", gen.GetName());
- Assert.AreEqual("System.String", gen.GetFullName());
+ Assert.AreEqual("System.String", gen.GetNameWithNamespace());
Assert.IsTrue(gen.GetAssemblyName().StartsWith("mscorlib,"));
// Nested args.
res = TypeNameParser.Parse(typeof(Dictionary<int, List<string>>).FullName);
Assert.AreEqual("Dictionary`2", res.GetName());
- Assert.AreEqual("System.Collections.Generic.Dictionary`2", res.GetFullName());
+ Assert.AreEqual("System.Collections.Generic.Dictionary`2", res.GetNameWithNamespace());
Assert.IsNull(res.GetAssemblyName());
Assert.AreEqual(2, res.Generics.Count);
gen = res.Generics.Last();
Assert.AreEqual("List`1", gen.GetName());
- Assert.AreEqual("System.Collections.Generic.List`1", gen.GetFullName());
+ Assert.AreEqual("System.Collections.Generic.List`1", gen.GetNameWithNamespace());
Assert.IsTrue(gen.GetAssemblyName().StartsWith("mscorlib,"));
Assert.AreEqual(1, gen.Generics.Count);
gen = gen.Generics.Single();
Assert.AreEqual("String", gen.GetName());
- Assert.AreEqual("System.String", gen.GetFullName());
+ Assert.AreEqual("System.String", gen.GetNameWithNamespace());
Assert.IsTrue(gen.GetAssemblyName().StartsWith("mscorlib,"));
// Nested class.
res = TypeNameParser.Parse(typeof(NestedGeneric<int>).FullName);
Assert.AreEqual("NestedGeneric`1", res.GetName());
- Assert.AreEqual("Apache.Ignite.Core.Tests.Binary.TypeNameParserTest+NestedGeneric`1", res.GetFullName());
+ Assert.AreEqual("Apache.Ignite.Core.Tests.Binary.TypeNameParserTest+NestedGeneric`1", res.GetNameWithNamespace());
gen = res.Generics.Single();
Assert.AreEqual("Int32", gen.GetName());
- Assert.AreEqual("System.Int32", gen.GetFullName());
+ Assert.AreEqual("System.Int32", gen.GetNameWithNamespace());
res = TypeNameParser.Parse(typeof(NestedGeneric<int>.NestedGeneric2<string>).AssemblyQualifiedName);
Assert.AreEqual("NestedGeneric2`1", res.GetName());
Assert.AreEqual("Apache.Ignite.Core.Tests.Binary.TypeNameParserTest+NestedGeneric`1+NestedGeneric2`1",
- res.GetFullName());
+ res.GetNameWithNamespace());
Assert.AreEqual(2, res.Generics.Count);
Assert.AreEqual("Int32", res.Generics.First().GetName());
@@ -163,9 +200,30 @@ namespace Apache.Ignite.Core.Tests.Binary
[Test]
public void TestArrays()
{
+ var res = TypeNameParser.Parse("Int32[]");
+ Assert.AreEqual("Int32", res.GetName());
+ Assert.AreEqual("Int32", res.GetNameWithNamespace());
+ Assert.AreEqual("Int32[]", res.GetFullName());
+ Assert.AreEqual("[]", res.GetArray());
+
+ res = TypeNameParser.Parse("Int32[*]");
+ Assert.AreEqual("Int32", res.GetName());
+ Assert.AreEqual("Int32", res.GetNameWithNamespace());
+ Assert.AreEqual("Int32[*]", res.GetFullName());
+ Assert.AreEqual("[*]", res.GetArray());
+
+ res = TypeNameParser.Parse("List`1[[Int32]][]");
+ Assert.AreEqual("List`1", res.GetName());
+ Assert.AreEqual("List`1", res.GetNameWithNamespace());
+ Assert.AreEqual("List`1[[Int32]][]", res.GetFullName());
+ Assert.AreEqual("[]", res.GetArray());
+
CheckType(typeof(int[]));
+ CheckType(typeof(int).MakeArrayType(1));
CheckType(typeof(int[,]));
+ CheckType(typeof(int[,,]));
CheckType(typeof(int[][]));
+ CheckType(typeof(int[,,,][,,]));
CheckType(typeof(List<int>[]));
CheckType(typeof(List<int>[,]));
@@ -184,12 +242,9 @@ namespace Apache.Ignite.Core.Tests.Binary
Assert.Throws<IgniteException>(() => TypeNameParser.Parse("x["));
Assert.Throws<IgniteException>(() => TypeNameParser.Parse("x[[]"));
Assert.Throws<IgniteException>(() => TypeNameParser.Parse("x`["));
- Assert.Throws<IgniteException>(() => TypeNameParser.Parse("x`]"));
Assert.Throws<IgniteException>(() => TypeNameParser.Parse("x`[ ]"));
Assert.Throws<IgniteException>(() => TypeNameParser.Parse("x,"));
- Assert.Throws<IgniteException>(() => TypeNameParser.Parse("x`x"));
Assert.Throws<IgniteException>(() => TypeNameParser.Parse("x`2[x"));
- Assert.Throws<IgniteException>(() => TypeNameParser.Parse("x`2xx"));
}
/// <summary>
@@ -207,7 +262,7 @@ namespace Apache.Ignite.Core.Tests.Binary
if (res.Generics == null)
{
- Assert.AreEqual(type.FullName, res.GetFullName() + res.GetArray());
+ Assert.AreEqual(type.FullName, res.GetNameWithNamespace() + res.GetArray());
}
Assert.AreEqual(type.FullName.Length + 2, res.AssemblyStart);
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeResolverTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeResolverTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeResolverTest.cs
index 7d37584..6ed1a5f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeResolverTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeResolverTest.cs
@@ -21,6 +21,7 @@ namespace Apache.Ignite.Core.Tests.Binary
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+ using Apache.Ignite.Core.Binary;
using Apache.Ignite.Core.Impl.Binary;
using Apache.Ignite.Core.Tests.TestDll;
using NUnit.Framework;
@@ -31,6 +32,35 @@ namespace Apache.Ignite.Core.Tests.Binary
public class TypeResolverTest
{
/// <summary>
+ /// Tests basic types.
+ /// </summary>
+ [Test]
+ public void TestBasicTypes()
+ {
+ var resolver = new TypeResolver();
+
+ Assert.AreEqual(typeof(int), resolver.ResolveType("System.Int32"));
+ Assert.AreEqual(GetType(), resolver.ResolveType(GetType().FullName));
+
+ Assert.IsNull(resolver.ResolveType("invalidType"));
+ }
+
+ /// <summary>
+ /// Tests basic types.
+ /// </summary>
+ [Test]
+ public void TestBasicTypesSimpleMapper()
+ {
+ var resolver = new TypeResolver();
+ var mapper = BinaryBasicNameMapper.SimpleNameInstance;
+
+ Assert.AreEqual(typeof(int), resolver.ResolveType("Int32", nameMapper: mapper));
+ Assert.AreEqual(GetType(), resolver.ResolveType("TypeResolverTest", nameMapper: mapper));
+
+ Assert.IsNull(resolver.ResolveType("invalidType", nameMapper: mapper));
+ }
+
+ /// <summary>
/// Tests generic type resolve.
/// </summary>
[Test]
@@ -67,6 +97,80 @@ namespace Apache.Ignite.Core.Tests.Binary
}
/// <summary>
+ /// Tests generic type resolve.
+ /// </summary>
+ [Test]
+ public void TestGenericsSimpleName()
+ {
+ var resolver = new TypeResolver();
+ var mapper = BinaryBasicNameMapper.SimpleNameInstance;
+
+ Assert.AreEqual(typeof(TestGenericBinarizable<int>),
+ resolver.ResolveType("TestGenericBinarizable`1[[Int32]]", nameMapper: mapper));
+
+ Assert.IsNull(resolver.ResolveType("TestGenericBinarizable`1[[Invalid-Type]]", nameMapper: mapper));
+
+ var testTypes = new[]
+ {
+ typeof (TestGenericBinarizable<int>),
+ typeof (TestGenericBinarizable<string>),
+ typeof (TestGenericBinarizable<TestGenericBinarizable<int>>),
+ typeof (TestGenericBinarizable<List<Tuple<int, string>>>),
+ typeof (TestGenericBinarizable<List<TestGenericBinarizable<List<Tuple<int, string>>>>>),
+ typeof (List<TestGenericBinarizable<List<TestGenericBinarizable<List<Tuple<int, string>>>>>>),
+ typeof (TestGenericBinarizable<int, string>),
+ typeof (TestGenericBinarizable<int, TestGenericBinarizable<string>>),
+ typeof (TestGenericBinarizable<int, string, Type>),
+ typeof (TestGenericBinarizable<int, string, TestGenericBinarizable<int, string, Type>>)
+ };
+
+ foreach (var type in testTypes)
+ {
+ var typeName = mapper.GetTypeName(type.AssemblyQualifiedName);
+ var resolvedType = resolver.ResolveType(typeName, nameMapper: mapper);
+ Assert.AreEqual(type, resolvedType);
+ }
+ }
+
+ /// <summary>
+ /// Tests array type resolve.
+ /// </summary>
+ [Test]
+ public void TestArrays()
+ {
+ var resolver = new TypeResolver();
+
+ Assert.AreEqual(typeof(int[]), resolver.ResolveType("System.Int32[]"));
+ Assert.AreEqual(typeof(int[][]), resolver.ResolveType("System.Int32[][]"));
+ Assert.AreEqual(typeof(int[,,][,]), resolver.ResolveType("System.Int32[,][,,]"));
+
+ Assert.AreEqual(typeof(int).MakeArrayType(1), resolver.ResolveType("System.Int32[*]"));
+
+ Assert.AreEqual(typeof(TestGenericBinarizable<TypeResolverTest>[]),
+ resolver.ResolveType("Apache.Ignite.Core.Tests.TestGenericBinarizable`1" +
+ "[[Apache.Ignite.Core.Tests.Binary.TypeResolverTest]][]"));
+ }
+
+ /// <summary>
+ /// Tests array type resolve.
+ /// </summary>
+ [Test]
+ public void TestArraysSimpleName()
+ {
+ var resolver = new TypeResolver();
+ var mapper = BinaryBasicNameMapper.SimpleNameInstance;
+
+ Assert.AreEqual(typeof(int[]), resolver.ResolveType("Int32[]", nameMapper: mapper));
+ Assert.AreEqual(typeof(int[][]), resolver.ResolveType("Int32[][]", nameMapper: mapper));
+ Assert.AreEqual(typeof(int[,,][,]), resolver.ResolveType("Int32[,][,,]", nameMapper: mapper));
+
+ Assert.AreEqual(typeof(int).MakeArrayType(1), resolver.ResolveType("Int32[*]", nameMapper: mapper));
+
+ Assert.AreEqual(typeof(TestGenericBinarizable<TypeResolverTest>[]),
+ resolver.ResolveType("TestGenericBinarizable`1[[TypeResolverTest]][]", nameMapper: mapper));
+ }
+
+ /// <summary>
/// Tests loading a type from referenced assembly that is not yet loaded.
/// </summary>
[Test]
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
index 1fa993b..01277e1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
@@ -30,7 +30,6 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
using Apache.Ignite.Core.Cache.Configuration;
using Apache.Ignite.Core.Cache.Query;
using Apache.Ignite.Core.Common;
- using Apache.Ignite.Core.Impl.Binary;
using NUnit.Framework;
/// <summary>
@@ -442,7 +441,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
[Test]
public void TestScanQueryBinary([Values(true, false)] bool loc)
{
- CheckScanQuery<BinaryObject>(loc, true);
+ CheckScanQuery<IBinaryObject>(loc, true);
}
/// <summary>
@@ -460,7 +459,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
[Test]
public void TestScanQueryPartitionsBinary([Values(true, false)] bool loc)
{
- CheckScanQueryPartitions<BinaryObject>(loc, true);
+ CheckScanQueryPartitions<IBinaryObject>(loc, true);
}
/// <summary>
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DeploymentTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DeploymentTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DeploymentTest.cs
index 74da531..cb97076 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DeploymentTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DeploymentTest.cs
@@ -79,6 +79,7 @@ namespace Apache.Ignite.Core.Tests
{
"-springConfigUrl=" + springFile,
"-jvmClasspath=" + classpath,
+ "-assembly=" + Path.GetFileName(GetType().Assembly.Location),
"-J-ea",
"-J-Xms512m",
"-J-Xmx512m"
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTest.cs
index e041fd7..9389185 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTest.cs
@@ -17,12 +17,12 @@
namespace Apache.Ignite.Core.Tests.Examples
{
+ extern alias ExamplesDll;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Apache.Ignite.Core.Tests.Process;
- using Apache.Ignite.ExamplesDll.Compute;
using NUnit.Framework;
/// <summary>
@@ -130,7 +130,8 @@ namespace Apache.Ignite.Core.Tests.Examples
var args = new List<string>
{
"-configFileName=" + _configPath,
- "-assembly=" + typeof(AverageSalaryJob).Assembly.Location
+ "-assembly=" + typeof(ExamplesDll::Apache.Ignite.ExamplesDll.Compute.AverageSalaryJob)
+ .Assembly.Location
};
var proc = new IgniteProcess(args.ToArray());
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryBasicNameMapper.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryBasicNameMapper.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryBasicNameMapper.cs
index 0a6406b..c75303f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryBasicNameMapper.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryBasicNameMapper.cs
@@ -57,7 +57,7 @@ namespace Apache.Ignite.Core.Binary
if (parsedName.Generics == null)
{
// Generics are rare, use simpler logic for the common case.
- var res = IsSimpleName ? parsedName.GetName() : parsedName.GetFullName();
+ var res = IsSimpleName ? parsedName.GetName() : parsedName.GetNameWithNamespace();
var arr = parsedName.GetArray();
@@ -71,7 +71,7 @@ namespace Apache.Ignite.Core.Binary
var nameFunc = IsSimpleName
? (Func<TypeNameParser, string>) (x => x.GetName())
- : (x => x.GetFullName());
+ : (x => x.GetNameWithNamespace());
return BuildTypeName(parsedName, new StringBuilder(), nameFunc).ToString();
}
@@ -94,7 +94,7 @@ namespace Apache.Ignite.Core.Binary
var generics = typeName.Generics;
- if (generics != null)
+ if (generics != null && generics.Count > 0) // Generics are non-null but empty when unbound.
{
sb.Append('[');
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
index 555a042..df30a6d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
@@ -161,17 +161,17 @@ namespace Apache.Ignite.Core.Impl.Binary
/// Registers the type.
/// </summary>
/// <param name="id">The identifier.</param>
- /// <param name="type">The type.</param>
+ /// <param name="typeName">The type name.</param>
/// <returns>True if registration succeeded; otherwise, false.</returns>
- public bool RegisterType(int id, Type type)
+ public bool RegisterType(int id, string typeName)
{
- Debug.Assert(type != null);
+ Debug.Assert(typeName != null);
Debug.Assert(id != BinaryUtils.TypeUnregistered);
return DoOutOp((int) Op.RegisterType, w =>
{
w.WriteInt(id);
- w.WriteString(type.AssemblyQualifiedName);
+ w.WriteString(typeName);
}) == True;
}
@@ -180,12 +180,9 @@ namespace Apache.Ignite.Core.Impl.Binary
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns>Type or null.</returns>
- public Type GetType(int id)
+ public string GetTypeName(int id)
{
- var typeName = DoOutInOp((int) Op.GetType, w => w.WriteInt(id),
- r => Marshaller.StartUnmarshal(r).ReadString());
-
- return new TypeResolver().ResolveType(typeName);
+ return DoOutInOp((int) Op.GetType, w => w.WriteInt(id), r => Marshaller.StartUnmarshal(r).ReadString());
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
index 49bab77..a5c6814 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
@@ -704,13 +704,13 @@ namespace Apache.Ignite.Core.Impl.Binary
{
throw new BinaryObjectException(string.Format(
"Unknown type ID: {0}. " +
- "This usually indicates missing BinaryConfiguration." +
+ "This usually indicates missing BinaryConfiguration. " +
"Make sure that all nodes have the same BinaryConfiguration.", hdr.TypeId));
}
throw new BinaryObjectException(string.Format(
- "No matching type found for object [typeId={0}, typeName={1}]." +
- "This usually indicates that assembly with specified type is not loaded on a node." +
+ "No matching type found for object [typeId={0}, typeName={1}]. " +
+ "This usually indicates that assembly with specified type is not loaded on a node. " +
"When using Apache.Ignite.exe, make sure to load assemblies with -assembly parameter.",
desc.TypeId, desc.TypeName));
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
index 4707ce2..ea2964a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
@@ -439,13 +439,21 @@ namespace Apache.Ignite.Core.Impl.Binary
if (!userType)
return null;
- if (requiresType)
+ if (requiresType && _ignite != null)
{
// Check marshaller context for dynamically registered type.
- var type = _ignite == null ? null : _ignite.BinaryProcessor.GetType(typeId);
+ var typeName = _ignite.BinaryProcessor.GetTypeName(typeId);
- if (type != null)
- return AddUserType(type, typeId, GetTypeName(type), true, desc);
+ if (typeName != null)
+ {
+ var type = new TypeResolver().ResolveType(typeName, nameMapper:
+ _cfg.NameMapper ?? GetDefaultNameMapper());
+
+ if (type != null)
+ {
+ return AddUserType(type, typeId, GetTypeName(type), true, desc);
+ }
+ }
}
var meta = GetBinaryType(typeId);
@@ -475,7 +483,7 @@ namespace Apache.Ignite.Core.Impl.Binary
var typeName = GetTypeName(type);
var typeId = GetTypeId(typeName, _cfg.IdMapper);
- var registered = _ignite != null && _ignite.BinaryProcessor.RegisterType(typeId, type);
+ var registered = _ignite != null && _ignite.BinaryProcessor.RegisterType(typeId, typeName);
return AddUserType(type, typeId, typeName, registered, desc);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeNameParser.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeNameParser.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeNameParser.cs
index 527d47c..a925770 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeNameParser.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeNameParser.cs
@@ -78,6 +78,11 @@ namespace Apache.Ignite.Core.Impl.Binary
public int NameEnd { get; private set; }
/// <summary>
+ /// Gets the name end.
+ /// </summary>
+ public int FullNameEnd { get; private set; }
+
+ /// <summary>
/// Gets the start of the assembly name.
/// </summary>
public int AssemblyStart { get; private set; }
@@ -116,7 +121,7 @@ namespace Apache.Ignite.Core.Impl.Binary
/// <summary>
/// Gets the full type name (with namespace).
/// </summary>
- public string GetFullName()
+ public string GetNameWithNamespace()
{
if (NameEnd < 0)
return null;
@@ -125,6 +130,14 @@ namespace Apache.Ignite.Core.Impl.Binary
}
/// <summary>
+ /// Gets the full name (with namespace, generics and arrays).
+ /// </summary>
+ public string GetFullName()
+ {
+ return _typeName.Substring(_start, FullNameEnd - _start + 1);
+ }
+
+ /// <summary>
/// Gets the array part.
/// </summary>
public string GetArray()
@@ -164,6 +177,7 @@ namespace Apache.Ignite.Core.Impl.Binary
ParseTypeName();
ParseGeneric();
ParseArrayDefinition();
+ FullNameEnd = End ? _pos : _pos - 1;
ParseAssemblyName();
}
@@ -183,7 +197,7 @@ namespace Apache.Ignite.Core.Impl.Binary
if (Char == '`')
{
- // Non-null ist indicates detected generic type.
+ // Non-null list indicates detected generic type.
Generics = Generics ?? new List<TypeNameParser>();
}
@@ -207,6 +221,12 @@ namespace Apache.Ignite.Core.Impl.Binary
return;
}
+ if (End || Char == ',')
+ {
+ // Open (unbound) generic.
+ return;
+ }
+
if (Char != '[')
{
throw new IgniteException("Invalid generic type name, number must be followed by '[': " + _typeName);
@@ -274,15 +294,18 @@ namespace Apache.Ignite.Core.Impl.Binary
{
if (!bracket)
{
- throw new IgniteException("Invalid array specification: " + _typeName);
+ ArrayEnd = _pos - 1;
+ return;
}
bracket = false;
}
- else if (Char == ',')
+ else if (Char == ',' || Char == '*')
{
if (!bracket)
+ {
break;
+ }
}
else
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs
index 68222d4..fa59d62 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs
@@ -23,6 +23,7 @@ namespace Apache.Ignite.Core.Impl.Binary
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
+ using Apache.Ignite.Core.Binary;
/// <summary>
/// Resolves types by name.
@@ -37,10 +38,11 @@ namespace Apache.Ignite.Core.Impl.Binary
/// </summary>
/// <param name="typeName">Name of the type.</param>
/// <param name="assemblyName">Optional, name of the assembly.</param>
+ /// <param name="nameMapper">The name mapper.</param>
/// <returns>
/// Resolved type.
/// </returns>
- public Type ResolveType(string typeName, string assemblyName = null)
+ public Type ResolveType(string typeName, string assemblyName = null, IBinaryNameMapper nameMapper = null)
{
Debug.Assert(!string.IsNullOrEmpty(typeName));
@@ -55,8 +57,8 @@ namespace Apache.Ignite.Core.Impl.Binary
var parsedType = TypeNameParser.Parse(typeName);
// Partial names should be resolved by scanning assemblies.
- return ResolveType(assemblyName, parsedType, AppDomain.CurrentDomain.GetAssemblies())
- ?? ResolveTypeInReferencedAssemblies(assemblyName, parsedType);
+ return ResolveType(assemblyName, parsedType, AppDomain.CurrentDomain.GetAssemblies(), nameMapper)
+ ?? ResolveTypeInReferencedAssemblies(assemblyName, parsedType, nameMapper);
}
/// <summary>
@@ -65,12 +67,14 @@ namespace Apache.Ignite.Core.Impl.Binary
/// <param name="assemblyName">Name of the assembly.</param>
/// <param name="typeName">Name of the type.</param>
/// <param name="assemblies">Assemblies to look in.</param>
+ /// <param name="nameMapper">The name mapper.</param>
/// <returns>
/// Resolved type.
/// </returns>
- private static Type ResolveType(string assemblyName, TypeNameParser typeName, ICollection<Assembly> assemblies)
+ private static Type ResolveType(string assemblyName, TypeNameParser typeName, ICollection<Assembly> assemblies,
+ IBinaryNameMapper nameMapper)
{
- var type = ResolveNonGenericType(assemblyName, typeName.GetFullName(), assemblies);
+ var type = ResolveNonGenericType(assemblyName, typeName.GetNameWithNamespace(), assemblies, nameMapper);
if (type == null)
{
@@ -79,9 +83,54 @@ namespace Apache.Ignite.Core.Impl.Binary
if (type.IsGenericTypeDefinition && typeName.Generics != null)
{
- var genArgs = typeName.Generics.Select(x => ResolveType(assemblyName, x, assemblies)).ToArray();
+ var genArgs = typeName.Generics
+ .Select(x => ResolveType(assemblyName, x, assemblies, nameMapper)).ToArray();
- return type.MakeGenericType(genArgs);
+ if (genArgs.Any(x => x == null))
+ {
+ return null;
+ }
+
+ type = type.MakeGenericType(genArgs);
+ }
+
+ return MakeArrayType(type, typeName.GetArray());
+ }
+
+ /// <summary>
+ /// Makes the array type according to spec, e.g. "[,][]".
+ /// </summary>
+ private static Type MakeArrayType(Type type, string arraySpec)
+ {
+ if (arraySpec == null)
+ {
+ return type;
+ }
+
+ int? rank = null;
+
+ foreach (var c in arraySpec)
+ {
+ switch (c)
+ {
+ case '[':
+ rank = null;
+ break;
+
+ case ',':
+ rank = rank == null ? 2 : rank + 1;
+ break;
+
+ case '*':
+ rank = 1;
+ break;
+
+ case ']':
+ type = rank == null
+ ? type.MakeArrayType()
+ : type.MakeArrayType(rank.Value);
+ break;
+ }
}
return type;
@@ -93,8 +142,10 @@ namespace Apache.Ignite.Core.Impl.Binary
/// <param name="assemblyName">Name of the assembly.</param>
/// <param name="typeName">Name of the type.</param>
/// <param name="assemblies">The assemblies.</param>
+ /// <param name="nameMapper">The name mapper.</param>
/// <returns>Resolved type, or null.</returns>
- private static Type ResolveNonGenericType(string assemblyName, string typeName, ICollection<Assembly> assemblies)
+ private static Type ResolveNonGenericType(string assemblyName, string typeName,
+ ICollection<Assembly> assemblies, IBinaryNameMapper nameMapper)
{
// Fully-qualified name can be resolved with system mechanism.
var type = Type.GetType(typeName, false);
@@ -115,15 +166,7 @@ namespace Apache.Ignite.Core.Impl.Binary
return null;
}
- // Trim assembly qualification
- var commaIdx = typeName.IndexOf(',');
-
- if (commaIdx > 0)
- {
- typeName = typeName.Substring(0, commaIdx);
- }
-
- return assemblies.Select(a => a.GetType(typeName, false, false)).FirstOrDefault(x => x != null);
+ return assemblies.Select(a => FindType(a, typeName, nameMapper)).FirstOrDefault(x => x != null);
}
/// <summary>
@@ -131,10 +174,12 @@ namespace Apache.Ignite.Core.Impl.Binary
/// </summary>
/// <param name="assemblyName">Name of the assembly.</param>
/// <param name="typeName">Name of the type.</param>
+ /// <param name="nameMapper">The name mapper.</param>
/// <returns>
/// Resolved type.
/// </returns>
- private Type ResolveTypeInReferencedAssemblies(string assemblyName, TypeNameParser typeName)
+ private Type ResolveTypeInReferencedAssemblies(string assemblyName, TypeNameParser typeName,
+ IBinaryNameMapper nameMapper)
{
ResolveEventHandler resolver = (sender, args) => GetReflectionOnlyAssembly(args.Name);
@@ -142,7 +187,8 @@ namespace Apache.Ignite.Core.Impl.Binary
try
{
- var result = ResolveType(assemblyName, typeName, GetNotLoadedReferencedAssemblies().ToArray());
+ var result = ResolveType(assemblyName, typeName, GetNotLoadedReferencedAssemblies().ToArray(),
+ nameMapper);
if (result == null)
return null;
@@ -150,7 +196,7 @@ namespace Apache.Ignite.Core.Impl.Binary
// result is from ReflectionOnly assembly, load it properly into current domain
var asm = AppDomain.CurrentDomain.Load(result.Assembly.GetName());
- return asm.GetType(result.FullName);
+ return FindType(asm, result.FullName, nameMapper);
}
finally
{
@@ -215,5 +261,34 @@ namespace Apache.Ignite.Core.Impl.Binary
roots.Push(refAsm);
}
}
+
+ /// <summary>
+ /// Finds the type within assembly.
+ /// </summary>
+ private static Type FindType(Assembly asm, string typeName, IBinaryNameMapper mapper)
+ {
+ if (mapper == null)
+ {
+ return asm.GetType(typeName);
+ }
+
+ return GetAssemblyTypesSafe(asm).FirstOrDefault(x => mapper.GetTypeName(x.FullName) == typeName);
+ }
+
+ /// <summary>
+ /// Safely gets all assembly types.
+ /// </summary>
+ private static IEnumerable<Type> GetAssemblyTypesSafe(Assembly asm)
+ {
+ try
+ {
+ return asm.GetTypes();
+ }
+ catch (ReflectionTypeLoadException ex)
+ {
+ // Handle the situation where some assembly dependencies are not available.
+ return ex.Types.Where(x => x != null);
+ }
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba21c46c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs
index f8ff85c..033de7e 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Memory/PlatformMemoryStream.cs
@@ -893,7 +893,7 @@ namespace Apache.Ignite.Core.Impl.Memory
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
- protected virtual void Dispose(bool disposing)
+ private void Dispose(bool disposing)
{
if (disposing)
SynchronizeOutput();