public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (this._settings == null)
            {
                var realConverter = serializer.GetStatefulConverter <MultiSearchResponseJsonConverter>();
                var mr            = realConverter.ReadJson(reader, objectType, existingValue, serializer) as MultiSearchResponse;
                return(mr);
            }

            var response   = new MultiSearchResponse();
            var jsonObject = JObject.Load(reader);

            var docsJarray = (JArray)jsonObject["responses"];

            if (docsJarray == null)
            {
                return(response);
            }
            var multiSearchDescriptor = this._request;

            if (this._request == null)
            {
                return(multiSearchDescriptor);
            }

            var withMeta = docsJarray.Zip(this._request.Operations, (doc, desc) => new MultiHitTuple {
                Hit = doc, Descriptor = desc
            });
            var originalResolver = serializer.ContractResolver;

            foreach (var m in withMeta)
            {
                var descriptor           = m.Descriptor.Value;
                var concreteTypeSelector = descriptor.TypeSelector;
                var baseType             = m.Descriptor.Value.ClrType ?? typeof(object);

                var generic = MakeDelegateMethodInfo.MakeGenericMethod(baseType);

                if (concreteTypeSelector != null)
                {
                    var state = typeof(ConcreteTypeConverter <>).CreateGenericInstance(baseType, concreteTypeSelector) as JsonConverter;
                    if (state != null)
                    {
                        var elasticSerializer = new JsonNetSerializer(this._settings, state);

                        generic.Invoke(null, new object[] { m, elasticSerializer.Serializer, response.Responses, this._settings });
                        continue;
                    }
                }
                generic.Invoke(null, new object[] { m, serializer, response.Responses, this._settings });
            }

            return(response);
        }
Exemple #2
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (this._settings == null)
            {
                var realConverter = serializer.GetStatefulConverter <MultiSearchResponseJsonConverter>();
                return(realConverter.ReadJson(reader, objectType, existingValue, serializer));
            }

            var response   = new MultiSearchResponse();
            var jsonObject = JObject.Load(reader);

            var docsJarray = (JArray)jsonObject["responses"];

            if (docsJarray == null)
            {
                return(response);
            }
            var multiSearchDescriptor = this._request;

            if (this._request == null)
            {
                return(multiSearchDescriptor);
            }

            IEnumerable <SearchHitTuple> withMeta;

            if (this._request is IMultiSearchRequest multiSearch)
            {
                withMeta = docsJarray.Zip(multiSearch.Operations,
                                          (doc, desc) => new SearchHitTuple {
                    Hit = doc, Descriptor = new KeyValuePair <string, ICovariantSearchRequest>(desc.Key, desc.Value)
                });
            }
            else
            {
                if (!(this._request is IMultiSearchTemplateRequest multiSearchTemplate))
                {
                    throw new InvalidOperationException($"Request must be an instance of {nameof(IMultiSearchRequest)} or {nameof(IMultiSearchTemplateRequest)}");
                }

                withMeta = docsJarray.Zip(multiSearchTemplate.Operations,
                                          (doc, desc) => new SearchHitTuple {
                    Hit = doc, Descriptor = new KeyValuePair <string, ICovariantSearchRequest>(desc.Key, desc.Value)
                });
            }

            foreach (var m in withMeta)
            {
                var descriptor           = m.Descriptor.Value;
                var concreteTypeSelector = descriptor.TypeSelector;
                var baseType             = m.Descriptor.Value.ClrType ?? typeof(object);
                var cachedDelegate       = serializer.GetConnectionSettings().Inferrer.CreateSearchResponseDelegates.GetOrAdd(baseType, t =>
                {
                    // Compile a delegate from an expression
                    var methodInfo           = MakeDelegateMethodInfo.MakeGenericMethod(t);
                    var tupleParameter       = Expression.Parameter(typeof(SearchHitTuple), "tuple");
                    var serializerParameter  = Expression.Parameter(typeof(JsonSerializer), "serializer");
                    var multiHitCollection   = Expression.Parameter(typeof(IDictionary <string, object>), "collection");
                    var parameterExpressions = new[] { tupleParameter, serializerParameter, multiHitCollection };
                    var call   = Expression.Call(null, methodInfo, parameterExpressions);
                    var lambda = Expression.Lambda <Action <SearchHitTuple, JsonSerializer, IDictionary <string, object> > >(call, parameterExpressions);
                    return(lambda.Compile());
                });

                if (concreteTypeSelector != null)
                {
                    var state = (JsonConverter)typeof(ConcreteTypeConverter <>).CreateGenericInstance(baseType, concreteTypeSelector);
                    if (state != null)
                    {
                        var elasticSerializer = this._settings.CreateStateful(state);
                        if (elasticSerializer != null)
                        {
                            cachedDelegate(m, elasticSerializer.Serializer, response.Responses);
                            continue;
                        }
                    }
                }

                cachedDelegate(m, serializer, response.Responses);
            }

            return(response);
        }