Skip to content

Instantly share code, notes, and snippets.

@varren
Created September 23, 2017 05:47
Show Gist options
  • Save varren/60a24433a1c5c3155afb4a8fd0f72dc1 to your computer and use it in GitHub Desktop.
Save varren/60a24433a1c5c3155afb4a8fd0f72dc1 to your computer and use it in GitHub Desktop.
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.InputStream;
import java.util.*;
/**
* Created by varren on 23.09.17.
*/
public class Test {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
InputStream data = Test.class.getClassLoader()
.getResourceAsStream("original.json");
List<Element> types = mapper.readValue(data,
new TypeReference<List<Element>>() {
});
InputStream postProcessData = Test.class.getClassLoader()
.getResourceAsStream("reference.json");
List<Element> postTypes = mapper.readValue(postProcessData,
new TypeReference<List<Element>>() {
});
merge(types, postTypes);
System.out.print(mapper.writeValueAsString(types));
}
private static void merge(List<Element> one, List<Element> two){
for(Element original: one){
for (Element updated:two){
if(Objects.equals(original.type, updated.type)){
original.mergeWith(updated);
}
}
}
}
public static class Element {
@JsonProperty("type")
private String type;
@JsonProperty("attributes")
private List<Attribute> attributes = new ArrayList<>();
public List<Attribute> getAttributes() {
return attributes;
}
public void setAttributes(List<Attribute> attributes) {
this.attributes = attributes;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public void mergeWith(Element updated) {
for (Attribute oldAttr : attributes) {
for (Attribute newAttr : updated.attributes) {
if (Objects.equals(oldAttr.name, newAttr.name)) {
oldAttr.getAdditionalProperties()
.putAll(newAttr.getAdditionalProperties());
}
}
}
}
}
public static class Attribute{
@JsonProperty("name")
private String name;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
}
@varren
Copy link
Author

varren commented Sep 23, 2017

How you can improve this code really depends on what is your goal her. And there is nothing wrong to parse json at place with readTree if you only need to merge it, but your version is really hard to read. And do you actually need to hardcore all the fields like com.person.EmployeeInfo and displayName or do you want a generic solution... I prefere to create pojo classes (with http://www.jsonschema2pojo.org/ for example) and use them, because it is much more flexible and provides lots of features, like json validation.

You can improve it, remove @JsonAnySetter and @JsonAnyGetter in Attribute class and provide only valid fields like String name, List validOperators and String displayName(probably you can have some other valid fields), but this will also force you to wright more merge code.

If you actually instantiate com.person.EmployeeInfo and com.person.SalaryInfo in your code you could also use @JsonTypeInfo annotations More info: http://www.baeldung.com/jackson-annotations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment