Class MetadataCopier

Object
MetadataCopier

public class MetadataCopier extends Object
Performs deep copies of given metadata instances. This class performs copies, not clones, since the copied metadata may not be instances of the same class than the original metadata. This class performs the following steps:
  • Get the implementation class of the given metadata instance.
  • Create a new instance of the implementation class using the public no-argument constructor.
  • Invoke all non-deprecated setter methods on the new instance with the corresponding value from the given metadata.
  • If any of the values copied in above step is itself a metadata, recursively performs deep copy on those metadata instances too.
This copier may be used for converting metadata tree of unknown implementations (for example the result of a call to Metadata­Source​.lookup(Class, String)) into instances of Abstract­Metadata. The copier may also be used if a modifiable metadata is desired after the original metadata has been made final.

Default implementation copies all copiable children, regardless their state. Static factory methods allow to construct some variants, for example skipping the copy of unmodifiable metadata instances since they can be safely shared.

This class supports cyclic graphs in the metadata tree. It may return the given metadata object directly if the implementation class does not provide any setter method.

This class is not thread-safe. In multi-threads environment, each thread should use its own Metadata­Copier instance.

Since:
0.8
  • Constructor Details

    • MetadataCopier

      public MetadataCopier(MetadataStandard standard)
      Creates a new metadata copier.
      Parameters:
      standard - the default metadata standard to use for object that are not Abstract­Metadata instances, or null if none.
  • Method Details

    • forModifiable

      public static MetadataCopier forModifiable(MetadataStandard standard)
      Creates a new metadata copier which avoid copying unmodifiable metadata. More specifically, any Modifiable­Metadata instance in final state will be kept as-is; those final metadata will not be copied since they can be safely shared.
      Parameters:
      standard - the default metadata standard to use for object that are not Abstract­Metadata instances, or null if none.
      Returns:
      a metadata copier which skip the copy of unmodifiable metadata.
      Since:
      1.0
    • copy

      public Object copy(Object metadata)
      Performs a potentially deep copy of a metadata object of unknown type. The return value does not need to be of the same class than the argument.
      Parameters:
      metadata - the metadata object to copy, or null.
      Returns:
      a copy of the given metadata object, or null if the given argument is null.
      Throws:
      Unsupported­Operation­Exception - if there is no implementation class for a metadata to copy, or an implementation class does not provide a public default constructor.
    • copy

      public <T> T copy(Class<T> type, T metadata)
      Performs a potentially deep copy of the given metadata object. This method is preferred to copy(Object) when the type is known. The specified type should be an interface, not an implementation (for example Metadata, not Default­Metadata).
      Type Parameters:
      T - compile-time value of the type argument.
      Parameters:
      type - the interface of the metadata object to copy.
      metadata - the metadata object to copy, or null.
      Returns:
      a copy of the given metadata object, or null if the given argument is null.
      Throws:
      Illegal­Argument­Exception - if type is an implementation class instead of interface.
      Unsupported­Operation­Exception - if there is no implementation class for a metadata to copy, or an implementation class does not provide a public default constructor.
    • copyRecursively

      protected Object copyRecursively(Class<?> type, Object metadata)
      Performs the actual copy operation on a single metadata instance. This method is invoked by all public copy(…) method with the root metadata object in argument, then is invoked recursively for all properties in that metadata object. If a metadata property is a collection, then this method is invoked for each element in the collection.

      Subclasses can override this method if they need some control on the copy process.

      Parameters:
      type - the interface of the metadata object to copy, or null if unspecified.
      metadata - the metadata object to copy, or null.
      Returns:
      a copy of the given metadata object, or null if the given argument is null.
      Throws:
      Unsupported­Operation­Exception - if there is no implementation class for a metadata to copy, or an implementation class does not provide a public default constructor.
    • getCurrentPropertyPath

      protected List<String> getCurrentPropertyPath()
      Returns the path to the currently copied property. Each element in the list is the UML identifier of a property. Element at index 0 is the name of the property of the root metadata object being copied. Element at index 1 is the name of a property which is a children of above property, etc.

      The returned list is valid only during copy­Recursively(Class, Object) method execution. The content of this list become undetermined after the copy­Recursively method returned.

      Returns:
      the path to the currently copied property.
      Since:
      1.0