Some use cases require a custom mutable definition to be created from the code to achieve some dynamic functionality (e.g. choose/move dialogs and some other features in UI). Usually such definitions are derived from the existing definitions via cloning in order to prevent modification of the source definition (which is a singleton).
So far we've been using the deep cloning approach provided by com.rits.cloning.Cloner utility. However, there were numerous problems with cloning the definition objects that aren't merest POJO under the hood. Especially big pain is caused by the proxied objects (e.g. i18n'ized definitions, decorated definitions etc) since internally such objects normally have cross-references (e.g. CGLIB tooling fields) which cause cycle dependencies and stack overflow exceptions during cloning.
I propose to cure the problem in 'homeopathic' way - create a utility that would allow generate a mutable proxy wrapper object:
- all the setter invocations are recorded
- getter invocations either return explicit value provided via a setter previously or a value from the wrapped (i.e. cloned object). When such 'fallback' value is returned - it is also wrapped in the same way.
The wrap call could look like this:
final ChooseDialogDefinition chooseDialogDefinition = MutableWrapper.wrap(definition);
final ConfiguredChooseDialogDefinition chooseDialogDefinition = MutableWrapper.wrap(definition, ConfiguredChooseDialogDefinition.class);
This way we gain the following:
- the original object is never modified,
- wrapper has the same polymorphic type as the wrapped value (as opposed to the 'dumb wrapper' approach which technically can only have that iff all definition classes would implement a virtual method T createWrapper(T) of some Wrappable interface)
- solution would never care about the nature of the wrapped object - it would only care about the return value,
- 'cloning' would happen lazily - sub-objects would be wrapped iff they are queried via a getter.