-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merge different configuration objects, and create the basic foundation for profiles-in-validator #480
Merge different configuration objects, and create the basic foundation for profiles-in-validator #480
Changes from 42 commits
36e12b6
1c12796
0b10a5d
0d775b9
f90eb6e
2843c76
77c0bc5
9ab5eed
e9a400e
087cb20
8352855
dac1d65
f275742
3936f20
f93e4ba
05f712e
b170ee1
0a45c63
515293b
2c2d596
46f7c1b
7be9310
3fd252f
d44da52
fc87f59
b6db851
369e6fa
7f7f813
829285d
c1a9ccf
2aebbc7
45193ba
8dc8122
6ca8763
54bc403
1e47e7c
4674ce9
80fed3f
daba570
316f0ce
7fc4f18
0b4f8e8
e4d2026
5e60466
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
import java.lang.reflect.Field; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class GeneralUtils { | ||
|
||
|
@@ -76,12 +77,33 @@ public static void toJsonFile(File file, Object target) { | |
} | ||
} | ||
|
||
public static <T> T deepCopy(T endpoint1, Class<T> valueType) { | ||
@SuppressWarnings("unchecked") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there anything interesting and useful we can comment here about why we need this? Is it the return or the cast? Same question for the other functions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved the @SuppressWarnings to specific field declarations where the type-cast is more clear. |
||
public static <T> T deepCopy(T object) { | ||
Class<?> targetClass = object.getClass(); | ||
try { | ||
return OBJECT_MAPPER.readValue(toJsonString(endpoint1), | ||
valueType); | ||
return (T) OBJECT_MAPPER.readValue(toJsonString(object), targetClass); | ||
} catch (Exception e) { | ||
throw new RuntimeException("While making deep copy of " + valueType.getName(), e); | ||
throw new RuntimeException("While making deep copy of " + targetClass.getName(), e); | ||
} | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public static <T> T mergeObject(Object destination, Object source) { | ||
Map<String, Object> target = JsonUtil.asMap(destination); | ||
mergeObject(target, JsonUtil.asMap(source)); | ||
return (T) JsonUtil.convertTo(destination.getClass(), target); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public static void mergeObject(Map<String, Object> target, Map<String, Object> source) { | ||
for (String key : source.keySet()) { | ||
Object targetValue = target.get(key); | ||
Object sourceValue = source.get(key); | ||
if (targetValue instanceof Map && sourceValue instanceof Map) { | ||
mergeObject((Map<String, Object>) targetValue, (Map<String, Object>) sourceValue); | ||
} else { | ||
target.put(key, sourceValue); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package com.google.udmi.util; | ||
|
||
import static com.google.udmi.util.GeneralUtils.deepCopy; | ||
import static com.google.udmi.util.GeneralUtils.mergeObject; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNotEquals; | ||
import static org.junit.Assert.assertNull; | ||
|
||
import com.google.common.collect.ImmutableMap; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import org.junit.Test; | ||
|
||
/** | ||
* Tests for general utilities. | ||
*/ | ||
public class GeneralUtilsTest { | ||
|
||
@Test | ||
@SuppressWarnings("unchecked") | ||
public void testDeepCopy() { | ||
Map<String, Object> original = getBaseMap(); | ||
Map<String, Object> copy = deepCopy(original); | ||
assertEquals("copy is equal", original, copy); | ||
((Map<String, String>) copy.get("C")).put("F", "H"); | ||
assertNotEquals("copy is not equal", original, copy); | ||
} | ||
|
||
private Map<String, Object> getBaseMap() { | ||
Map<String, Object> original = new HashMap<>(); | ||
original.put("A", "B"); | ||
original.put("C", ImmutableMap.of("D", "E", "F", "G")); | ||
return original; | ||
} | ||
|
||
@Test | ||
@SuppressWarnings("unchecked") | ||
public void testMergeObject() { | ||
final Map<String, Object> target = deepCopy(getBaseMap()); | ||
final Map<String, Object> originalTarget = deepCopy(target); | ||
final Map<String, Object> source = deepCopy(target); | ||
source.put("X", "Y"); | ||
final Map<String, String> sourceC = (Map<String, String>) source.get("C"); | ||
sourceC.put("D", "Q"); | ||
sourceC.put("H", "I"); | ||
final Map<String, Object> originalSource = deepCopy(source); | ||
mergeObject(target, source); | ||
assertEquals("unmolested source", originalSource, source); | ||
assertNotEquals("changed target", target, originalTarget); | ||
assertNull("original X", originalTarget.get("X")); | ||
assertEquals("target X", "Y", target.get("X")); | ||
final Map<String, String> originalC = (Map<String, String>) originalTarget.get("C"); | ||
assertEquals("original C.D", "E", originalC.get("D")); | ||
assertEquals("original C.F", "G", originalC.get("F")); | ||
assertNull("original C.H", originalC.get("H")); | ||
final Map<String, String> targetC = (Map<String, String>) target.get("C"); | ||
assertEquals("target C.D", "Q", targetC.get("D")); | ||
assertEquals("target C.F", "G", targetC.get("F")); | ||
assertEquals("target C.H", "I", targetC.get("H")); | ||
} | ||
|
||
@Test | ||
public void testMergeTyped() { | ||
Container source = new Container(); | ||
Container target = new Container(); | ||
source.anInt = 2; | ||
source.bool = true; | ||
target.string = "hello"; | ||
target.bool = false; | ||
Container merged = mergeObject(target, source); | ||
assertEquals("source a", 2, source.anInt); | ||
assertEquals("target a", 0, target.anInt); | ||
assertEquals("merged a", 2, merged.anInt); | ||
assertNull("source b", source.string); | ||
assertEquals("target b", "hello", target.string); | ||
assertEquals("merged b", "hello", merged.string); | ||
assertEquals("source c", true, source.bool); | ||
assertEquals("target c", false, target.bool); | ||
assertEquals("merged c", true, merged.bool); | ||
} | ||
|
||
/** | ||
* Simple test container class. | ||
*/ | ||
public static class Container { | ||
|
||
public int anInt; | ||
public String string; | ||
public Boolean bool; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was redundant with a build operation lower down in the stack, so just removing to reduce overall code.