From 45234ba5bc83939922fd6887834fff1100e41deb Mon Sep 17 00:00:00 2001 From: Jeff Nelson Date: Wed, 20 Jun 2018 06:51:53 -0700 Subject: [PATCH] add upsert method to AnyMaps --- .../com/cinchapi/common/collect/AnyMaps.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/main/java/com/cinchapi/common/collect/AnyMaps.java b/src/main/java/com/cinchapi/common/collect/AnyMaps.java index 5402e9d..cc2a646 100644 --- a/src/main/java/com/cinchapi/common/collect/AnyMaps.java +++ b/src/main/java/com/cinchapi/common/collect/AnyMaps.java @@ -19,6 +19,8 @@ import java.util.List; import java.util.Map; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.primitives.Ints; /** @@ -67,6 +69,46 @@ public static void rename(String key, String newKey, } } + /** + * Put or update the value associated with the {@code path} within a + * possibly nested {@link Map} that contains other maps and collections as values. + * + * @param path a navigable path key (e.g. foo.bar.1.baz) + * @param value + * @param map + * @return + */ + @SuppressWarnings("unchecked") + public static Object upsert(String path, Object value, + Map map) { + List components = Lists.newArrayList(path.split("\\.")); + Map source = (Map) map; + String key; + do { + key = components.remove(0); + //TODO: handle case where the key is a Number + if(!components.isEmpty()) { + try { + Map next = (Map) source + .get(key); + if(next == null) { + next = Maps.newHashMap(); + source.put(key, next); + } + source = next; + + } + catch (ClassCastException e) { + throw new IllegalArgumentException("Illegal path " + path + + ". The component mapped from " + key + + " is not an Map"); + } + } + } + while (!components.isEmpty()); + return source.put(key, value); + } + /** * Return a possibly nested value in a {@link Map} that contains other maps * and collections as values.