diff --git a/plugins/ingest/src/main/java/org/elasticsearch/ingest/Data.java b/plugins/ingest/src/main/java/org/elasticsearch/ingest/Data.java index d27360c0380..690dad062bb 100644 --- a/plugins/ingest/src/main/java/org/elasticsearch/ingest/Data.java +++ b/plugins/ingest/src/main/java/org/elasticsearch/ingest/Data.java @@ -19,8 +19,13 @@ package org.elasticsearch.ingest; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.xcontent.support.XContentMapValues; +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -47,9 +52,30 @@ public final class Data { return (T) XContentMapValues.extractValue(path, document); } - public void addField(String field, Object value) { + /** + * add `value` to path in document. If path does not exist, + * nested hashmaps will be put in as parent key values until + * leaf key name in path is reached. + * + * @param path The path within the document in dot-notation + * @param value The value to put in for the path key + */ + public void addField(String path, Object value) { modified = true; - document.put(field, value); + + String[] pathElements = Strings.splitStringToArray(path, '.'); + + String writeKey = pathElements[pathElements.length - 1]; + Map inner = document; + + for (int i = 0; i < pathElements.length - 1; i++) { + if (!inner.containsKey(pathElements[i])) { + inner.put(pathElements[i], new HashMap()); + } + inner = (HashMap) inner.get(pathElements[i]); + } + + inner.put(writeKey, value); } public String getIndex() { diff --git a/plugins/ingest/src/test/java/org/elasticsearch/ingest/DataTests.java b/plugins/ingest/src/test/java/org/elasticsearch/ingest/DataTests.java new file mode 100644 index 00000000000..bafc0c92356 --- /dev/null +++ b/plugins/ingest/src/test/java/org/elasticsearch/ingest/DataTests.java @@ -0,0 +1,71 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch 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. + */ + +package org.elasticsearch.ingest; + +import org.elasticsearch.test.ESTestCase; +import org.junit.Before; + +import java.util.HashMap; + +import static org.hamcrest.Matchers.*; + +public class DataTests extends ESTestCase { + + private Data data; + + @Before + public void setData() { + data = new Data("index", "type", "id", + new HashMap() {{ + put("foo", "bar"); + put("fizz", new HashMap() {{ + put("buzz", "hello world"); + }}); + }}); + } + + public void testSimpleGetProperty() { + assertThat(data.getProperty("foo"), equalTo("bar")); + } + + public void testNestedGetProperty() { + assertThat(data.getProperty("fizz.buzz"), equalTo("hello world")); + } + + public void testSimpleAddField() { + data.addField("new_field", "foo"); + assertThat(data.getDocument().get("new_field"), equalTo("foo")); + } + + public void testNestedAddField() { + data.addField("a.b.c.d", "foo"); + assertThat(data.getProperty("a.b.c.d"), equalTo("foo")); + } + + public void testAddFieldOnExistingField() { + data.addField("foo", "newbar"); + assertThat(data.getProperty("foo"), equalTo("newbar")); + } + + public void testAddFieldOnExistingParent() { + data.addField("fizz.new", "bar"); + assertThat(data.getProperty("fizz.new"), equalTo("bar")); + } +}