package crate.elasticsearch.searchinto.mapping; import java.util.HashMap; import java.util.Map; import org.elasticsearch.ElasticSearchException; import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.index.mapper.internal.IdFieldMapper; import org.elasticsearch.index.mapper.internal.IndexFieldMapper; import org.elasticsearch.index.mapper.internal.SourceFieldMapper; import org.elasticsearch.index.mapper.internal.TTLFieldMapper; import org.elasticsearch.index.mapper.internal.TimestampFieldMapper; import org.elasticsearch.index.mapper.internal.TypeFieldMapper; public class FieldWriter { private final String name; protected Object value; private BuilderWriter writer; private final static ImmutableMap<String, BuilderWriter> writers; static { writers = MapBuilder.<String, BuilderWriter>newMapBuilder().put( SourceFieldMapper.NAME, new BuilderWriter() { @Override public void write(IndexRequestBuilder builder, Object value) { builder.source = (Map<String, Object>) value; } }).put(IndexFieldMapper.NAME, new BuilderWriter() { @Override public void write(IndexRequestBuilder builder, Object value) { builder.request.index(value.toString()); } }).put(IdFieldMapper.NAME, new BuilderWriter() { @Override public void write(IndexRequestBuilder builder, Object value) { builder.request.id(value.toString()); } }).put(TypeFieldMapper.NAME, new BuilderWriter() { @Override public void write(IndexRequestBuilder builder, Object value) { builder.request.type(value.toString()); } }).put(TimestampFieldMapper.NAME, new BuilderWriter() { @Override public void write(IndexRequestBuilder builder, Object value) { builder.request.timestamp(value.toString()); } }).put(TTLFieldMapper.NAME, new BuilderWriter() { @Override public void write(IndexRequestBuilder builder, Object value) { builder.request.ttl((Long) value); } }).put("_version", new BuilderWriter() { @Override public void write(IndexRequestBuilder builder, Object value) { builder.request.version((Long) value); } }).immutableMap(); } static abstract class BuilderWriter { public abstract void write(IndexRequestBuilder builder, Object value); } class SourceObjectWriter extends BuilderWriter { private final String name; SourceObjectWriter(String name) { this.name = name; } /** * Method to recursively create a nested object */ private void writeMap(Map<String, Object> root, Object value, String part) { if (part.contains(".")) { String[] parts = part.split("\\.", 2); Object o = root.get(parts[0]); if (o == null) { o = new HashMap<String, Object>(); } else if (!(o instanceof Map)) { throw new ElasticSearchException("Error on rewriting objects: Mixed objects and values"); } Map<String, Object> sub = (Map<String, Object>) o; writeMap(sub, value, parts[1]); root.put(parts[0], sub); } else { if (((Map<String, Object>) root).get(part) instanceof Map) { throw new ElasticSearchException("Error on rewriting objects: Mixed objects and values"); } root.put(part, value); } } @Override public void write(IndexRequestBuilder builder, Object value) { if (value != null) { writeMap(builder.source, value, name); } } } public FieldWriter(String name) { this.name = name; initWriter(); } private void initWriter() { if (name.startsWith("_")) { writer = writers.get(name); } if (writer == null) { writer = new SourceObjectWriter(name); } } public void setValue(Object value) { this.value = value; } public IndexRequestBuilder toRequestBuilder(IndexRequestBuilder builder) { writer.write(builder, value); return builder; } }