/* SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. * * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. 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. */ using System; using OpenSearch.Client.Specification.IndicesApi; namespace OpenSearch.Client { public class MappingWalker { private readonly IMappingVisitor _visitor; public MappingWalker(IMappingVisitor visitor) { visitor.ThrowIfNull(nameof(visitor)); _visitor = visitor; } public void Accept(GetMappingResponse response) { if (response?.Indices == null) return; foreach (var indexMapping in response.Indices) { if (indexMapping.Value?.Mappings == null) continue; Accept(indexMapping.Value.Mappings); } } public void Accept(ITypeMapping mapping) { if (mapping == null) return; _visitor.Visit(mapping); Accept(mapping.Properties); } private static void Visit<TProperty>(IProperty prop, Action<TProperty> act) where TProperty : class, IProperty { if (!(prop is TProperty t)) return; act(t); } public void Accept(IProperties properties) { if (properties == null) return; foreach (var kv in properties) { var field = kv.Value; var type = field.Type; var ft = type.ToEnum<FieldType>(); switch (ft) { case FieldType.Text: Visit<ITextProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.Keyword: Visit<IKeywordProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.SearchAsYouType: Visit<ISearchAsYouTypeProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.HalfFloat: case FieldType.ScaledFloat: case FieldType.Float: case FieldType.Double: case FieldType.Byte: case FieldType.Short: case FieldType.Integer: case FieldType.Long: Visit<INumberProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.Date: Visit<IDateProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.DateNanos: Visit<IDateNanosProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.Boolean: Visit<IBooleanProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.Binary: Visit<IBinaryProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.Object: Visit<IObjectProperty>(field, t => { _visitor.Visit(t); _visitor.Depth += 1; Accept(t.Properties); _visitor.Depth -= 1; }); break; case FieldType.Nested: Visit<INestedProperty>(field, t => { _visitor.Visit(t); _visitor.Depth += 1; Accept(t.Properties); _visitor.Depth -= 1; }); break; case FieldType.Ip: Visit<IIpProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.GeoPoint: Visit<IGeoPointProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.GeoShape: Visit<IGeoShapeProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.Completion: Visit<ICompletionProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.Murmur3Hash: Visit<IMurmur3HashProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.TokenCount: Visit<ITokenCountProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.Percolator: Visit<IPercolatorProperty>(field, t => { _visitor.Visit(t); }); break; case FieldType.IntegerRange: Visit<IIntegerRangeProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.FloatRange: Visit<IFloatRangeProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.LongRange: Visit<ILongRangeProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.DoubleRange: Visit<IDoubleRangeProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.DateRange: Visit<IDateRangeProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.IpRange: Visit<IIpRangeProperty>(field, t => { _visitor.Visit(t); Accept(t.Fields); }); break; case FieldType.Join: Visit<IJoinProperty>(field, t => { _visitor.Visit(t); }); break; case FieldType.RankFeature: Visit<IRankFeatureProperty>(field, t => { _visitor.Visit(t); }); break; case FieldType.RankFeatures: Visit<IRankFeaturesProperty>(field, t => { _visitor.Visit(t); }); break; case FieldType.None: continue; } } } } }