org.apache.sis.metadata

## Class MetadataCopier

- Object
- - MetadataCopier

-     public class MetadataCopier
      extends Object

  Performs deep copies of given metadata instances. This class performs a 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 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 `MetadataCopier` instance.

  Recommended alternative: deep metadata copies are sometime useful when using an existing metadata as a template. But the `ModifiableMetadata​.unmodifiable()` method may provide a better way to use a metadata as a template, as it returns a snapshot and allows the caller to continue to modify the original metadata object and create new snapshots. Example:

      // Prepare a Citation to be used as a template.
      DefaultCitation citation = new DefaultCitation();
      citation.getCitedResponsibleParties(someAuthor);

      // Set the title and get a first snapshot.
      citation.setTitle(new SimpleInternationalString("A title"));
      Citation myFirstCitation = (Citation) citation.unmodifiable();

      // Change the title and get another snapshot.
      citation.setTitle(new SimpleInternationalString("Another title"));
      Citation mySecondCitation = (Citation) citation.unmodifiable();

  This approach allows sharing the children that have the same content, thus reducing memory usage. In above example, the `someAuthor` cited responsible party is the same instance in both citations. In comparison, deep copy operations unconditionally duplicate everything, no matter if it was needed or not. Nevertheless deep copies are still sometime useful, for example when we do not have the original `ModifiableMetadata` instance anymore.

  `MetadataCopier` is also useful for converting a metadata tree of unknown implementations (for example the result of a call to `MetadataSource​.lookup(Class, String)`) into instances of the public `AbstractMetadata` subclasses. But note that shallow copies as provided by the `castOrCopy(…)` static methods in each `AbstractMetadata` subclass are sometime sufficient.

  Since:
    0.8
  See Also:
    `ModifiableMetadata​.unmodifiable()`

  Defined in the `sis-metadata` module

- - ### Constructor Summary

    Constructors
    Constructor and Description
    `MetadataCopier(MetadataStandard standard)` Creates a new metadata copier.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `<T> T` | `copy(Class<T> type, T metadata)` Performs a potentially deep copy of the given metadata object.
    `Object` | `copy(Object metadata)` Performs a potentially deep copy of a metadata object of unknown type.
    `protected Object` | `copyRecursively(Class<?> type, Object metadata)` Performs the actual copy operation on a single metadata instance.

    - ### Methods inherited from class Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### MetadataCopier

          public MetadataCopier(MetadataStandard standard)

      Creates a new metadata copier.
      Parameters:
        `standard` - the default metadata standard to use for object that are not `AbstractMetadata` instances, or `null` if none.

  - ### Method Detail

    - #### 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:
        `UnsupportedOperationException` - 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.
      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:
        `UnsupportedOperationException` - 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:
        `UnsupportedOperationException` - if there is no implementation class for a metadata to copy, or an implementation class does not provide a public default constructor.

Copyright © 2010–2017 The Apache Software Foundation. All rights reserved.