I have a situation where I need to copy the contents (attributes) of one POJO instance to another instance of the same type, but only for non-null attributes/member and non-empty collections. For instance:
// Groovy pseudo-code
class Widget {
Fizz fizz
List<Buzz> buzzes
List<Foo> foos
Widget(Fizz fizz, List<Buzz> buzzes, List<Foo> foos) {
super()
this.fizz = fizz
this.buzz = buzz
this.foos = foos
}
}
class ExistentialCopier<T> {
T copyExistentialContents(T toCopy) {
// ???
}
}
class Driver {
static void main(String[] args) {
ExistentialCopier<Widget> widgetCopier = new ExistentialCopier<Widget>()
Fizz fizz = new Fizz()
Buzz b1, b2, b3
b1 = new Buzz()
b2 = null // <— note the NULL
b3 = new Buzz()
List<Buzz> buzzes = []
buzzes << b1
buzzes << b2
buzzes << b3
Widget w1 = new Widget(fizz, buzzes, null)
Widget w2 = widgetCopier.copyExistentialContents(w1)
// All of these return true.
assert w2.fizz == w1.fizz
assert w2.buzzes.get(0) == w1.buzzes.get(0)
assert w2.buzzes.get(1) == w1.buzzes.get(2) // because b2 was null, it didn’t copy over
assert w2.size() == 2 // again, b2 didn’t copy (it was null/nonexistent)
assert w2.fizzes == null
}
}
So what I’m looking for in ExistentialCopier
is:
- A way to be generic and handle any type,
Widgets
or otherwise (perhaps theT
generic will need to implement some interface (?) - For non-collections, copy
toCopy
’s non-null attributes - For collections, if
toCopy
’s collection is null, don’t copy it (level the copy’s respective collection null as well) - For collections, if a particular element/member is null, don’t copy it, otherwise, copy it
I feel like there is a Groovy way of accomplishing this, but perhaps this type of “Copy Only If Exists” pattern is well known and already solved by some open source library. Perhaps a solution best suited for bean-to-bean mapping utilities like Dozer null exclusions perhaps (which I have no experience with)?