Uploaded image for project: 'Magnolia'
  1. Magnolia
  2. MAGNOLIA-6693

Introduce proxy-based mutable wrapper utility as alternative to Cloner functionality

    XMLWordPrintable

    Details

    • Type: New Feature
    • Status: Closed
    • Priority: Neutral
    • Resolution: Fixed
    • Affects Version/s: 5.4.7
    • Fix Version/s: 5.4.8, 5.5
    • Component/s: None
    • Labels:
      None
    • Sprint:
      Basel 50, Basel 50
    • Story Points:
      8
    • Magnolia Release:
      5.4.8, 5.5

      Description

      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);
      or
      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.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              apchelintcev Aleksandr Pchelintcev
              Reporter:
              apchelintcev Aleksandr Pchelintcev
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0d
                  0d
                  Logged:
                  Time Spent - 6d
                  6d