You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/04/18 13:46:21 UTC
[36/62] [abbrv] ignite git commit: IGNITE-2398 .NET: Change default
name mapper behavior to full name
http://git-wip-us.apache.org/repos/asf/ignite/blob/3e3b91a8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
index cd3becf..737c7c4 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
@@ -1,4 +1,4 @@
-/*
+\ufeff/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
@@ -62,19 +62,6 @@ namespace Apache.Ignite.Core.Impl.Binary
_name = typeName;
}
- /// <summary>
- /// Constructor.
- /// </summary>
- /// <param name="cfg">Configuration.</param>
- /// <param name="name">Type name.</param>
- public BinarySurrogateTypeDescriptor(BinaryConfiguration cfg, string name)
- {
- _cfg = cfg;
- _name = name;
-
- _id = BinaryUtils.TypeId(name, cfg.NameMapper, cfg.IdMapper);
- }
-
/** <inheritDoc /> */
public Type Type
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/3e3b91a8/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
index ca2c9ae..0979ea5 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
@@ -22,9 +22,7 @@ namespace Apache.Ignite.Core.Impl.Binary
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
- using System.Globalization;
using System.IO;
- using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
@@ -1638,34 +1636,6 @@ namespace Apache.Ignite.Core.Impl.Binary
}
/**
- * <summary>Convert type name.</summary>
- * <param name="typeName">Type name.</param>
- * <param name="converter">Converter.</param>
- * <returns>Converted name.</returns>
- */
- public static string ConvertTypeName(string typeName, IBinaryNameMapper converter)
- {
- var typeName0 = typeName;
-
- try
- {
- if (converter != null)
- typeName = converter.GetTypeName(typeName);
- }
- catch (Exception e)
- {
- throw new BinaryObjectException("Failed to convert type name due to converter exception " +
- "[typeName=" + typeName + ", converter=" + converter + ']', e);
- }
-
- if (typeName == null)
- throw new BinaryObjectException("Name converter returned null name for type [typeName=" +
- typeName0 + ", converter=" + converter + "]");
-
- return typeName;
- }
-
- /**
* <summary>Convert field name.</summary>
* <param name="fieldName">Field name.</param>
* <param name="converter">Converter.</param>
@@ -1693,67 +1663,13 @@ namespace Apache.Ignite.Core.Impl.Binary
return fieldName;
}
- /**
- * <summary>Extract simple type name.</summary>
- * <param name="typeName">Type name.</param>
- * <returns>Simple type name.</returns>
- */
- public static string SimpleTypeName(string typeName)
- {
- int idx = typeName.LastIndexOf('.');
-
- return idx < 0 ? typeName : typeName.Substring(idx + 1);
- }
-
- /**
- * <summary>Resolve type ID.</summary>
- * <param name="typeName">Type name.</param>
- * <param name="nameMapper">Name mapper.</param>
- * <param name="idMapper">ID mapper.</param>
- */
- public static int TypeId(string typeName, IBinaryNameMapper nameMapper,
- IBinaryIdMapper idMapper)
- {
- Debug.Assert(typeName != null);
-
- typeName = ConvertTypeName(typeName, nameMapper);
-
- int id = 0;
-
- if (idMapper != null)
- {
- try
- {
- id = idMapper.GetTypeId(typeName);
- }
- catch (Exception e)
- {
- throw new BinaryObjectException("Failed to resolve type ID due to ID mapper exception " +
- "[typeName=" + typeName + ", idMapper=" + idMapper + ']', e);
- }
- }
-
- if (id == 0)
- id = GetStringHashCode(typeName);
-
- return id;
- }
-
/// <summary>
- /// Gets the name of the type.
+ /// Gets the SQL name of the type.
/// </summary>
- /// <param name="type">The type.</param>
- /// <returns>
- /// Simple type name for non-generic types; simple type name with appended generic arguments for generic types.
- /// </returns>
- public static string GetTypeName(Type type)
+ public static string GetSqlTypeName(Type type)
{
- if (!type.IsGenericType)
- return type.Name;
-
- var args = type.GetGenericArguments().Select(GetTypeName).Aggregate((x, y) => x + "," + y);
-
- return string.Format(CultureInfo.InvariantCulture, "{0}[{1}]", type.Name, args);
+ // SQL always uses simple type name without namespace, parent class, etc.
+ return type.FullName;
}
/**
@@ -1796,31 +1712,6 @@ namespace Apache.Ignite.Core.Impl.Binary
}
/// <summary>
- /// Compare contents of two byte array chunks.
- /// </summary>
- /// <param name="arr1">Array 1.</param>
- /// <param name="offset1">Offset 1.</param>
- /// <param name="len1">Length 1.</param>
- /// <param name="arr2">Array 2.</param>
- /// <param name="offset2">Offset 2.</param>
- /// <param name="len2">Length 2.</param>
- /// <returns>True if array chunks are equal.</returns>
- public static bool CompareArrays(byte[] arr1, int offset1, int len1, byte[] arr2, int offset2, int len2)
- {
- if (len1 == len2)
- {
- for (int i = 0; i < len1; i++)
- {
- if (arr1[offset1 + i] != arr2[offset2 + i])
- return false;
- }
-
- return true;
- }
- return false;
- }
-
- /// <summary>
/// Writes invocation result.
/// </summary>
/// <param name="writer">Writer.</param>
http://git-wip-us.apache.org/repos/asf/ignite/blob/3e3b91a8/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 b60ced9..4707ce2 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
@@ -407,7 +407,8 @@ namespace Apache.Ignite.Core.Impl.Binary
return _typeNameToDesc.TryGetValue(typeName, out desc)
? (IBinaryTypeDescriptor) desc
- : new BinarySurrogateTypeDescriptor(_cfg, typeName);
+ : new BinarySurrogateTypeDescriptor(_cfg,
+ GetTypeId(typeName, _cfg.IdMapper), typeName);
}
/// <summary>
@@ -444,7 +445,7 @@ namespace Apache.Ignite.Core.Impl.Binary
var type = _ignite == null ? null : _ignite.BinaryProcessor.GetType(typeId);
if (type != null)
- return AddUserType(type, typeId, BinaryUtils.GetTypeName(type), true, desc);
+ return AddUserType(type, typeId, GetTypeName(type), true, desc);
}
var meta = GetBinaryType(typeId);
@@ -471,8 +472,8 @@ namespace Apache.Ignite.Core.Impl.Binary
{
Debug.Assert(type != null);
- var typeName = BinaryUtils.GetTypeName(type);
- var typeId = BinaryUtils.TypeId(typeName, _cfg.NameMapper, _cfg.IdMapper);
+ var typeName = GetTypeName(type);
+ var typeId = GetTypeId(typeName, _cfg.IdMapper);
var registered = _ignite != null && _ignite.BinaryProcessor.RegisterType(typeId, type);
@@ -538,7 +539,7 @@ namespace Apache.Ignite.Core.Impl.Binary
private void AddUserType(BinaryConfiguration cfg, BinaryTypeConfiguration typeCfg, TypeResolver typeResolver)
{
// Get converter/mapper/serializer.
- IBinaryNameMapper nameMapper = typeCfg.NameMapper ?? _cfg.NameMapper;
+ IBinaryNameMapper nameMapper = typeCfg.NameMapper ?? _cfg.NameMapper ?? GetDefaultNameMapper();
IBinaryIdMapper idMapper = typeCfg.IdMapper ?? _cfg.IdMapper;
@@ -561,8 +562,8 @@ namespace Apache.Ignite.Core.Impl.Binary
}
// Type is found.
- var typeName = BinaryUtils.GetTypeName(type);
- int typeId = BinaryUtils.TypeId(typeName, nameMapper, idMapper);
+ var typeName = GetTypeName(type, nameMapper);
+ int typeId = GetTypeId(typeName, idMapper);
var affKeyFld = typeCfg.AffinityKeyFieldName ?? GetAffinityKeyFieldNameFromAttribute(type);
var serializer = GetSerializer(cfg, typeCfg, type, typeId, nameMapper, idMapper, _log);
@@ -572,9 +573,9 @@ namespace Apache.Ignite.Core.Impl.Binary
else
{
// Type is not found.
- string typeName = BinaryUtils.SimpleTypeName(typeCfg.TypeName);
+ string typeName = GetTypeName(typeCfg.TypeName, nameMapper);
- int typeId = BinaryUtils.TypeId(typeName, nameMapper, idMapper);
+ int typeId = GetTypeId(typeName, idMapper);
AddType(null, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, null,
typeCfg.AffinityKeyFieldName, typeCfg.IsEnum);
@@ -689,11 +690,15 @@ namespace Apache.Ignite.Core.Impl.Binary
serializer = serializer ?? new BinarySystemTypeSerializer<T>(ctor);
+ // System types always use simple name mapper.
+ var typeName = type.Name;
+
if (typeId == 0)
- typeId = BinaryUtils.TypeId(type.Name, null, null);
+ {
+ typeId = BinaryUtils.GetStringHashCode(typeName);
+ }
- AddType(type, typeId, BinaryUtils.GetTypeName(type), false, false, null, null, serializer, affKeyFldName,
- false);
+ AddType(type, typeId, typeName, false, false, null, null, serializer, affKeyFldName, false);
}
/// <summary>
@@ -756,5 +761,71 @@ namespace Apache.Ignite.Core.Impl.Binary
type.AssemblyQualifiedName);
}
}
+
+ /// <summary>
+ /// Gets the name of the type.
+ /// </summary>
+ private string GetTypeName(Type type, IBinaryNameMapper mapper = null)
+ {
+ return GetTypeName(type.AssemblyQualifiedName, mapper);
+ }
+
+ /// <summary>
+ /// Gets the name of the type.
+ /// </summary>
+ private string GetTypeName(string fullTypeName, IBinaryNameMapper mapper = null)
+ {
+ mapper = mapper ?? _cfg.NameMapper ?? GetDefaultNameMapper();
+
+ var typeName = mapper.GetTypeName(fullTypeName);
+
+ if (typeName == null)
+ {
+ throw new BinaryObjectException("IBinaryNameMapper returned null name for type [typeName=" +
+ fullTypeName + ", mapper=" + mapper + "]");
+ }
+
+ return typeName;
+ }
+
+ /// <summary>
+ /// Resolve type ID.
+ /// </summary>
+ /// <param name="typeName">Type name.</param>
+ /// <param name="idMapper">ID mapper.</param>
+ private static int GetTypeId(string typeName, IBinaryIdMapper idMapper)
+ {
+ Debug.Assert(typeName != null);
+
+ int id = 0;
+
+ if (idMapper != null)
+ {
+ try
+ {
+ id = idMapper.GetTypeId(typeName);
+ }
+ catch (Exception e)
+ {
+ throw new BinaryObjectException("Failed to resolve type ID due to ID mapper exception " +
+ "[typeName=" + typeName + ", idMapper=" + idMapper + ']', e);
+ }
+ }
+
+ if (id == 0)
+ {
+ id = BinaryUtils.GetStringHashCode(typeName);
+ }
+
+ return id;
+ }
+
+ /// <summary>
+ /// Gets the default name mapper.
+ /// </summary>
+ private static IBinaryNameMapper GetDefaultNameMapper()
+ {
+ return BinaryBasicNameMapper.FullNameInstance;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3e3b91a8/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
new file mode 100644
index 0000000..527d47c
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeNameParser.cs
@@ -0,0 +1,384 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Binary
+{
+ using System.Collections.Generic;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Impl.Common;
+
+ /// <summary>
+ /// Parses .NET-style type names and deconstructs them into parts.
+ /// </summary>
+ internal class TypeNameParser
+ {
+ /** */
+ private readonly int _start;
+
+ /** */
+ private readonly string _typeName;
+
+ /** */
+ private int _pos;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TypeNameParser" /> class.
+ /// </summary>
+ private TypeNameParser(string typeName, ref int pos)
+ {
+ _typeName = typeName;
+ _start = pos;
+ _pos = _start;
+
+ NameEnd = -1;
+ NameStart = 0;
+ AssemblyStart = -1;
+ AssemblyEnd = -1;
+ ArrayStart = -1;
+
+ Parse();
+
+ pos = _pos;
+ }
+
+ /// <summary>
+ /// Parses the specified type name.
+ /// </summary>
+ public static TypeNameParser Parse(string typeName)
+ {
+ IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+ int pos = 0;
+
+ return new TypeNameParser(typeName, ref pos);
+ }
+
+ /// <summary>
+ /// Gets the name start.
+ /// </summary>
+ public int NameStart { get; private set; }
+
+ /// <summary>
+ /// Gets the name end.
+ /// </summary>
+ public int NameEnd { get; private set; }
+
+ /// <summary>
+ /// Gets the start of the assembly name.
+ /// </summary>
+ public int AssemblyStart { get; private set; }
+
+ /// <summary>
+ /// Gets the start of the assembly name.
+ /// </summary>
+ public int AssemblyEnd { get; private set; }
+
+ /// <summary>
+ /// Gets the start of the array definition.
+ /// </summary>
+ public int ArrayStart { get; private set; }
+
+ /// <summary>
+ /// Gets the start of the array definition.
+ /// </summary>
+ public int ArrayEnd { get; private set; }
+
+ /// <summary>
+ /// Gets the generics.
+ /// </summary>
+ public ICollection<TypeNameParser> Generics { get; private set; }
+
+ /// <summary>
+ /// Gets the type name (without namespace).
+ /// </summary>
+ public string GetName()
+ {
+ if (NameEnd < 0)
+ return null;
+
+ return _typeName.Substring(NameStart, NameEnd - NameStart + 1);
+ }
+
+ /// <summary>
+ /// Gets the full type name (with namespace).
+ /// </summary>
+ public string GetFullName()
+ {
+ if (NameEnd < 0)
+ return null;
+
+ return _typeName.Substring(_start, NameEnd - _start + 1);
+ }
+
+ /// <summary>
+ /// Gets the array part.
+ /// </summary>
+ public string GetArray()
+ {
+ if (ArrayStart < 0)
+ return null;
+
+ return _typeName.Substring(ArrayStart, ArrayEnd - ArrayStart + 1);
+ }
+
+ /// <summary>
+ /// Gets assembly name part.
+ /// </summary>
+ public string GetAssemblyName()
+ {
+ if (AssemblyStart < 0)
+ return null;
+
+ return _typeName.Substring(AssemblyStart, AssemblyEnd - AssemblyStart + 1);
+ }
+
+ /// <summary>
+ /// Parses this instance.
+ /// </summary>
+ private void Parse()
+ {
+ // Example:
+ // System.Collections.Generic.List`1[[System.Int32[], mscorlib, Version=4.0.0.0, Culture=neutral,
+ // PublicKeyToken =b77a5c561934e089]][], mscorlib, Version=4.0.0.0, Culture=neutral,
+ // PublicKeyToken =b77a5c561934e089
+
+ // 1) Namespace+name, ends with '`' or '[' or ','
+ // 2) Generic, starts with '`'
+ // 3) Array, starts with '['
+ // 4) Assembly, starts with ',', ends with EOL or `]`
+
+ ParseTypeName();
+ ParseGeneric();
+ ParseArrayDefinition();
+ ParseAssemblyName();
+ }
+
+ /// <summary>
+ /// Parses the type name with namespace.
+ /// </summary>
+ private void ParseTypeName()
+ {
+ NameStart = _pos;
+
+ while (Shift())
+ {
+ if (Char == '.' || Char == '+')
+ {
+ NameStart = _pos + 1;
+ }
+
+ if (Char == '`')
+ {
+ // Non-null ist indicates detected generic type.
+ Generics = Generics ?? new List<TypeNameParser>();
+ }
+
+ if (Char == '[' || Char == ']' || Char == ',' || Char == ' ')
+ break;
+ }
+
+ NameEnd = End ? _pos : _pos - 1;
+ }
+
+ /// <summary>
+ /// Parses the generic part.
+ /// </summary>
+ private void ParseGeneric()
+ {
+ // Generics can be nested:
+ // UserQuery+Gen`1+Gen2`1[[System.Int32, mscorlib],[System.String, mscorlib]]
+
+ if (Generics == null)
+ {
+ return;
+ }
+
+ if (Char != '[')
+ {
+ throw new IgniteException("Invalid generic type name, number must be followed by '[': " + _typeName);
+ }
+
+ while (true)
+ {
+ RequireShift();
+
+ if (Char != '[')
+ {
+ throw new IgniteException("Invalid generic type name, '[' must be followed by '[': " + _typeName);
+ }
+
+ RequireShift();
+
+ Generics.Add(new TypeNameParser(_typeName, ref _pos));
+
+ if (Char != ']')
+ {
+ throw new IgniteException("Invalid generic type name, no matching ']': " + _typeName);
+ }
+
+ RequireShift();
+
+ if (Char == ']')
+ {
+ Shift();
+ return;
+ }
+
+ if (Char != ',')
+ {
+ throw new IgniteException("Invalid generic type name, expected ',': " + _typeName);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Parses the array definition.
+ /// </summary>
+ private void ParseArrayDefinition()
+ {
+ if (Char != '[')
+ return;
+
+ ArrayStart = _pos;
+
+ var bracket = true;
+
+ RequireShift();
+
+ while (true)
+ {
+ if (Char == '[')
+ {
+ if (bracket)
+ {
+ throw new IgniteException("Invalid array specification: " + _typeName);
+ }
+
+ bracket = true;
+ }
+ else if (Char == ']')
+ {
+ if (!bracket)
+ {
+ throw new IgniteException("Invalid array specification: " + _typeName);
+ }
+
+ bracket = false;
+ }
+ else if (Char == ',')
+ {
+ if (!bracket)
+ break;
+ }
+ else
+ {
+ if (bracket)
+ {
+ throw new IgniteException("Invalid array specification: " + _typeName);
+ }
+
+ break;
+ }
+
+ if (!Shift())
+ break;
+ }
+
+ ArrayEnd = Char == ']' ? _pos : _pos - 1;
+ }
+
+ /// <summary>
+ /// Parses assembly name part.
+ /// </summary>
+ private void ParseAssemblyName()
+ {
+ if (Char != ',')
+ return;
+
+ RequireShift();
+
+ SkipSpaces();
+
+ AssemblyStart = _pos;
+
+ while (Char != ']' && Shift())
+ {
+ // No-op.
+ }
+
+ AssemblyEnd = End ? _pos : _pos - 1;
+ }
+
+ /// <summary>
+ /// Shifts the position forward.
+ /// </summary>
+ private bool Shift()
+ {
+ if (_pos < _typeName.Length - 1)
+ {
+ _pos++;
+ return true;
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Requires position shift or throws an error.
+ /// </summary>
+ private void RequireShift()
+ {
+ if (!Shift())
+ {
+ throw new IgniteException("Invalid type name - not enough data: " + _typeName);
+ }
+ }
+
+ /// <summary>
+ /// Skips the spaces.
+ /// </summary>
+ private void SkipSpaces()
+ {
+ while (Char == ' ' && Shift())
+ {
+ // No-op.
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether we are at the end of the string.
+ /// </summary>
+ private bool End
+ {
+ get { return _pos >= _typeName.Length - 1; }
+ }
+
+ /// <summary>
+ /// Gets the current character.
+ /// </summary>
+ private char Char
+ {
+ get { return _typeName[_pos]; }
+ }
+
+ /** <inheritdoc /> */
+ public override string ToString()
+ {
+ return _typeName;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3e3b91a8/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 36dde4b..68222d4 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs
@@ -21,20 +21,14 @@ namespace Apache.Ignite.Core.Impl.Binary
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
- using System.Globalization;
using System.Linq;
using System.Reflection;
- using System.Text.RegularExpressions;
/// <summary>
/// Resolves types by name.
/// </summary>
internal class TypeResolver
{
- /** Regex to parse generic types from binary configuration. Allows nested generics in type arguments. */
- private static readonly Regex GenericTypeRegex =
- new Regex(@"([^`,\[\]]*)(?:`[0-9]+)?(?:\[((?:(?<br>\[)|(?<-br>\])|[^\[\]]*)+)\])?", RegexOptions.Compiled);
-
/** Assemblies loaded in ReflectionOnly mode. */
private readonly Dictionary<string, Assembly> _reflectionOnlyAssemblies = new Dictionary<string, Assembly>();
@@ -54,11 +48,15 @@ namespace Apache.Ignite.Core.Impl.Binary
var type = Type.GetType(typeName, false);
if (type != null)
+ {
return type;
+ }
+
+ var parsedType = TypeNameParser.Parse(typeName);
// Partial names should be resolved by scanning assemblies.
- return ResolveType(assemblyName, typeName, AppDomain.CurrentDomain.GetAssemblies())
- ?? ResolveTypeInReferencedAssemblies(assemblyName, typeName);
+ return ResolveType(assemblyName, parsedType, AppDomain.CurrentDomain.GetAssemblies())
+ ?? ResolveTypeInReferencedAssemblies(assemblyName, parsedType);
}
/// <summary>
@@ -70,10 +68,23 @@ namespace Apache.Ignite.Core.Impl.Binary
/// <returns>
/// Resolved type.
/// </returns>
- private static Type ResolveType(string assemblyName, string typeName, ICollection<Assembly> assemblies)
+ private static Type ResolveType(string assemblyName, TypeNameParser typeName, ICollection<Assembly> assemblies)
{
- return ResolveGenericType(assemblyName, typeName, assemblies) ??
- ResolveNonGenericType(assemblyName, typeName, assemblies);
+ var type = ResolveNonGenericType(assemblyName, typeName.GetFullName(), assemblies);
+
+ if (type == null)
+ {
+ return null;
+ }
+
+ if (type.IsGenericTypeDefinition && typeName.Generics != null)
+ {
+ var genArgs = typeName.Generics.Select(x => ResolveType(assemblyName, x, assemblies)).ToArray();
+
+ return type.MakeGenericType(genArgs);
+ }
+
+ return type;
}
/// <summary>
@@ -85,64 +96,34 @@ namespace Apache.Ignite.Core.Impl.Binary
/// <returns>Resolved type, or null.</returns>
private static Type ResolveNonGenericType(string assemblyName, string typeName, ICollection<Assembly> assemblies)
{
+ // Fully-qualified name can be resolved with system mechanism.
+ var type = Type.GetType(typeName, false);
+
+ if (type != null)
+ {
+ return type;
+ }
+
if (!string.IsNullOrEmpty(assemblyName))
+ {
assemblies = assemblies
.Where(x => x.FullName == assemblyName || x.GetName().Name == assemblyName).ToArray();
+ }
if (!assemblies.Any())
+ {
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(type => type != null);
- }
-
- /// <summary>
- /// Resolves the name of the generic type by resolving each generic arg separately
- /// and substituting it's fully qualified name.
- /// (Assembly.GetType finds generic types only when arguments are fully qualified).
- /// </summary>
- /// <param name="assemblyName">Name of the assembly.</param>
- /// <param name="typeName">Name of the type.</param>
- /// <param name="assemblies">Assemblies</param>
- /// <returns>Fully qualified generic type name, or null if argument(s) could not be resolved.</returns>
- private static Type ResolveGenericType(string assemblyName, string typeName, ICollection<Assembly> assemblies)
- {
- var match = GenericTypeRegex.Match(typeName);
-
- if (!match.Success || !match.Groups[2].Success)
- return null;
-
- // Try to construct generic type; each generic arg can also be a generic type.
- var genericArgs = GenericTypeRegex.Matches(match.Groups[2].Value)
- .OfType<Match>().Select(m => m.Value).Where(v => !string.IsNullOrWhiteSpace(v))
- .Select(v => ResolveType(null, TrimBrackets(v), assemblies)).ToArray();
-
- if (genericArgs.Any(x => x == null))
- return null;
-
- var genericType = ResolveNonGenericType(assemblyName,
- string.Format(CultureInfo.InvariantCulture, "{0}`{1}", match.Groups[1].Value, genericArgs.Length),
- assemblies);
-
- if (genericType == null)
- return null;
-
- return genericType.MakeGenericType(genericArgs);
- }
-
- /// <summary>
- /// Trims the brackets from generic type arg.
- /// </summary>
- private static string TrimBrackets(string s)
- {
- return s.StartsWith("[", StringComparison.Ordinal) && s.EndsWith("]", StringComparison.Ordinal)
- ? s.Substring(1, s.Length - 2)
- : s;
+ return assemblies.Select(a => a.GetType(typeName, false, false)).FirstOrDefault(x => x != null);
}
/// <summary>
@@ -153,7 +134,7 @@ namespace Apache.Ignite.Core.Impl.Binary
/// <returns>
/// Resolved type.
/// </returns>
- private Type ResolveTypeInReferencedAssemblies(string assemblyName, string typeName)
+ private Type ResolveTypeInReferencedAssemblies(string assemblyName, TypeNameParser typeName)
{
ResolveEventHandler resolver = (sender, args) => GetReflectionOnlyAssembly(args.Name);
http://git-wip-us.apache.org/repos/asf/ignite/blob/3e3b91a8/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheFieldsQueryProvider.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheFieldsQueryProvider.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheFieldsQueryProvider.cs
index e909575..c665fe7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheFieldsQueryProvider.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheFieldsQueryProvider.cs
@@ -168,7 +168,7 @@ namespace Apache.Ignite.Linq.Impl
/// </summary>
private void ValidateTableName()
{
- var validTableNames = GetValidTableNames();
+ var validTableNames = GetValidTableNames().Select(x => EscapeTableName(x)).ToArray();
if (!validTableNames.Contains(_tableName, StringComparer.OrdinalIgnoreCase))
{
@@ -201,7 +201,7 @@ namespace Apache.Ignite.Linq.Impl
/// </summary>
private static string GetTableName(QueryEntity e)
{
- return e.TableName ?? e.ValueTypeName.Split('.').Last();
+ return e.TableName ?? e.ValueTypeName;
}
/// <summary>
@@ -213,12 +213,16 @@ namespace Apache.Ignite.Linq.Impl
var validTableNames = GetValidTableNames();
if (validTableNames.Length == 1)
- return validTableNames[0];
+ {
+ return EscapeTableName(validTableNames[0]);
+ }
- var valueTypeName = cacheValueType.Name;
+ var valueTypeName = cacheValueType.FullName;
if (validTableNames.Contains(valueTypeName, StringComparer.OrdinalIgnoreCase))
- return valueTypeName;
+ {
+ return EscapeTableName(valueTypeName);
+ }
throw new CacheException(string.Format("Table name cannot be inferred for cache '{0}', " +
"please use AsCacheQueryable overload with tableName parameter. " +
@@ -227,6 +231,16 @@ namespace Apache.Ignite.Linq.Impl
}
/// <summary>
+ /// Escapes the name of the table: strips namespace and nested class qualifiers.
+ /// </summary>
+ private static string EscapeTableName(string valueTypeName)
+ {
+ var nsIndex = Math.Max(valueTypeName.LastIndexOf('.'), valueTypeName.LastIndexOf('+'));
+
+ return nsIndex > 0 ? valueTypeName.Substring(nsIndex + 1) : valueTypeName;
+ }
+
+ /// <summary>
/// Gets the item type of closed generic i enumerable.
/// </summary>
private static Type GetItemTypeOfClosedGenericIEnumerable(Type enumerableType, string argumentName)
http://git-wip-us.apache.org/repos/asf/ignite/blob/3e3b91a8/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
index 99712e3..3659158 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
@@ -338,8 +338,8 @@ namespace Apache.Ignite.Linq.Impl
var entity = cacheCfg.QueryEntities.FirstOrDefault(e =>
e.Aliases != null &&
- (e.KeyType == keyValTypes[0] || e.KeyTypeName == keyValTypes[0].Name) &&
- (e.ValueType == keyValTypes[1] || e.ValueTypeName == keyValTypes[1].Name));
+ (e.KeyType == keyValTypes[0] || e.KeyTypeName == keyValTypes[0].FullName) &&
+ (e.ValueType == keyValTypes[1] || e.ValueTypeName == keyValTypes[1].FullName));
if (entity == null)
return fieldName;