copy

Motivation

Sometimes it is necessary to create a deep copy of an object. There are various approaches to this. The “copy” plugin defines its own interface, contract, and definitions that are somewhat different from the standard java “java.lang.Cloneable” contract. The entry point generated in the source code is called createCopy, there are optionally also copy constructors.

Function

The copy plugin generates a deep clone method for each of the generated classes, based on the following assumptions:

  • Instances of any other classes implementing the com.kscs.util.jaxb.Copyable interface are copyable by the same semantics as “this”.

  • Objects implementing java.lang.Cloneable and not throwing “CloneNotSupportedException” are also reliably cloneable by their “clone” Method.

  • Objects not implementing java.lang.Cloneable or primitive types are assumed to be immutable, their references are copied over, they are not cloned.

  • Optionally, generates a “partial createCopy” method that takes a PropertyTree instance which represents a specification of the nodes in the object tree to copy. The PropertyTree is built up by an intuitive builder pattern:

      final PropertyTree excludeEmployees = PropertyTree.builder().with("company").with("employees").build();
    
  • There is also a type-safe way to build a PropertyPath instance by using a generated classes' Selector sub structure. The following will generate the same selection as above:

      final PropertyTree excludeEmployees = Business.Select.root().company().employees().build()
    

Then, you would partially clone an object tree like this:

	final BusinessPartner businessPartnerCopy = businessPartner.createCopy(excludeEmployees, PropertyTreeUse.EXCLUDE);

Which is the same as

	final BusinessPartner businessPartnerCopy = businessPartner.copyExcept(excludeEmployees);

This way, the copy of the original businessPartner will have no employees attached to the contained company. It is also possible to copy only a specific subset of the original object tree, excluding everything else. The inverse result of the above would be generated by:

	final BusinessPartner businessPartnerCopy = businessPartner.createCopy(excludeEmployees, PropertyTreeUse.INCLUDE);

or

	final BusinessPartner businessPartnerCopy = businessPartner.copyOnly(excludeEmployees);

which will result in a businessPartnerCopy where every property is set to null, except the company property, and in the attached company object, every property is null except “employees”.

This works for single and multi-valued properties, where for multi-valued properties, the property tree applies to all elements of the list of values in the same way. As of yet, there is no way to make a tree apply only to specific indexes in generated lists.

Limitations

  • The -narrow option is a somewhat special use case and should be used carefully.

Usage

-Xcopy

Options

-copy.partial={y|n} (y)

Generates an additional ‘createCopy’-method and copy-constructor (if constructors are to generated at all) that takes a PropertyTree instance to restrict the copy operation to selected nodes in the object tree.

-copy.generateTools={y|n} (y)

Generate utility classes as source code. If you say “no” here, you will have to add the plugin JAR to the runtime classpath of the generated class domain.

-copy.constructor={y|n} (y)

Generates a copy constructor on each of the classes generated from the current XSD model.

-copy.narrow={y|n} (n)

Uses copy constructors for all child nodes in the object tree as long as they are available. This will cause the new instance to be as narrow as possible to the declared types.

-copy.selectorClassName=<string> (Selector)

Name of the generated nested “Selector” builder class, used to build up a property tree for partial copy functionality. This setting will also affect the “fluent-builder” plugin if it is active and set to “copy-partial=y”.

-copy.rootSelectorClassName=<string> (Select)

Name of the generated nested static “Select” entry point class to be used by client code for the “partial copy” feature. This setting will also affect the “fluent-builder” plugin if it is active and set to “copy-partial=y”.