# Class IdentifiedObjectSet<T extends IdentifiedObject>

Object
AbstractCollection<T>
AbstractSet<T>
IdentifiedObjectSet<T>

Type Parameters:
  `T` - the type of objects to be included in this set.

All Implemented Interfaces:
  `Iterable<T>`, `Collection<T>`, `Set<T>`, `CheckedContainer<T>`, `Localized`

public class IdentifiedObjectSet<T extends IdentifiedObject> extends AbstractSet<T> implements CheckedContainer<T>, Localized
A lazy set of `IdentifiedObject` instances created from their authority codes only when first needed. This set delegates `IdentifiedObject` creation to the most appropriate `createFoo(String)` method of the `AuthorityFactory` given at construction time.

Elements can be added to this collection with calls to `addAuthorityCode(String)` for deferred object creation, or to `add(IdentifiedObject)` for objects that are already instantiated. This collection cannot contain two `IdentifiedObject` instances having the same identifier. However, the identifiers used by this class can be controlled by overriding the `getAuthorityCode(IdentifiedObject)` method.

Iterations over elements in this collection preserve insertion order.

## Purpose

`IdentifiedObjectSet` is useful mostly for implementers of authority factories rather than users. When used as the implementation of the set of coordinate operations between a pair of CRS, `IdentifiedObjectSet` can improve significantly the performances because some sets contain tens of entries (e.g., transformations from ED50 (EPSG:4230) to WGS 84 (EPSG:4326)), while users typically want to look for only the first entry.

## Exception handling

If the underlying factory failed to creates an object because of an unsupported operation method (`NoSuchIdentifierException`), the exception is logged at `Level​.WARNING` and the iteration continues. If the operation creation failed for any other kind of reason (`FactoryException`), then the exception is re-thrown as an unchecked `BackingStoreException`. This default behavior can be changed by overriding the `isRecoverableFailure(FactoryException)` method.

## Thread safety

This class is thread-safe if the underlying factory is also thread-safe. However, implementers are encouraged to wrap in unmodifiable set if they intent to cache `IdentifiedObjectSet` instances.

Since:
  0.7

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected final AuthorityFactory`
  `factory`
  The factory to use for creating `IdentifiedObject`s when first needed.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `IdentifiedObjectSet(AuthorityFactory factory, Class<T> type)`
  Creates an initially empty set.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `boolean`
  `add(T object)`
  Ensures that this collection contains the specified object.
  `void`
  `addAuthorityCode(String code)`
  Ensures that this collection contains an object for the specified authority code.
  `void`
  `clear()`
  Removes all of the elements from this collection.
  `boolean`
  `contains(Object object)`
  Returns `true` if this collection contains the specified `IdentifiedObject`.
  `protected T`
  `createObject(String code)`
  Creates an object for the specified authority code.
  `protected String`
  `getAuthorityCode(T object)`
  Returns the identifier for the specified object.
  `String[]`
  `getAuthorityCodes()`
  Returns the authority codes of all `IdentifiedObject`s contained in this collection, in insertion order.
  `Class<T>`
  `getElementType()`
  Returns the type of `IdentifiedObject` included in this set.
  `Locale`
  `getLocale()`
  Returns the locale to use for error messages and warnings.
  `protected boolean`
  `isRecoverableFailure(FactoryException exception)`
  Returns `true` if the specified exception should be handled as a recoverable failure.
  `Iterator<T>`
  `iterator()`
  Returns an iterator over the objects in this set.
  `boolean`
  `remove(Object object)`
  Removes the specified `IdentifiedObject` from this collection, if it is present.
  `boolean`
  `removeAll(Collection<?> collection)`
  Removes from this collection all of its elements that are contained in the specified collection.
  `void`
  `resolve(int n)`
  Ensures that the n first objects in this set are created.
  `void`
  `setAuthorityCodes(String... codes)`
  Sets the content of this collection to the object identified by the given codes.
  `int`
  `size()`
  Returns the number of objects available in this set.

  ### Methods inherited from class AbstractSet

  `equals, hashCode`

  ### Methods inherited from class AbstractCollection

  `addAll, containsAll, isEmpty, retainAll, toArray, toArray, toString`

  ### Methods inherited from class Object

  `clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

  ### Methods inherited from interface Collection

  `parallelStream, removeIf, stream, toArray`

  ### Methods inherited from interface Iterable

  `forEach`

  ### Methods inherited from interface Set

  `addAll, containsAll, isEmpty, retainAll, spliterator, toArray, toArray`

- ## Field Details

  - ### factory

    protected final AuthorityFactory factory
    The factory to use for creating `IdentifiedObject`s when first needed. This is the authority factory given at construction time.

- ## Constructor Details

  - ### IdentifiedObjectSet

    public IdentifiedObjectSet(AuthorityFactory factory, Class<T> type)
    Creates an initially empty set. The set can be populated after construction by calls to `addAuthorityCode(String)` for deferred `IdentifiedObject` creation, or to `add(IdentifiedObject)` for already instantiated objects.
    Parameters:
      `factory` - the factory to use for deferred `IdentifiedObject` instances creation.
      `type` - the type of objects included in this set.

- ## Method Details

  - ### getLocale

    public Locale getLocale()
    Returns the locale to use for error messages and warnings. The default implementation inherits the `factory` locale, if any.
    Specified by:
      `getLocale` in interface `Localized`
    Returns:
      the locale, or `null` if not explicitly defined.

  - ### getElementType

    public Class<T> getElementType()
    Returns the type of `IdentifiedObject` included in this set.
    Specified by:
      `getElementType` in interface `CheckedContainer<T extends IdentifiedObject>`
    Returns:
      the type of `IdentifiedObject` included in this set.

  - ### clear

    public void clear()
    Removes all of the elements from this collection.
    Specified by:
      `clear` in interface `Collection<T extends IdentifiedObject>`
    Specified by:
      `clear` in interface `Set<T extends IdentifiedObject>`
    Overrides:
      `clear` in class `AbstractCollection<T extends IdentifiedObject>`

  - ### size

    public int size()
    Returns the number of objects available in this set. Note that this number may decrease during the iteration process if the creation of some `IdentifiedObject`s failed.
    Specified by:
      `size` in interface `Collection<T extends IdentifiedObject>`
    Specified by:
      `size` in interface `Set<T extends IdentifiedObject>`
    Specified by:
      `size` in class `AbstractCollection<T extends IdentifiedObject>`
    Returns:
      the number of objects available in this set.

  - ### getAuthorityCodes

    public String[] getAuthorityCodes()
    Returns the authority codes of all `IdentifiedObject`s contained in this collection, in insertion order. This method does not trig the creation of any object.
    Returns:
      the authority codes in iteration order.

  - ### setAuthorityCodes

    public void setAuthorityCodes(String... codes)
    Sets the content of this collection to the object identified by the given codes. For any code in the given sequence, this method will preserve the corresponding `IdentifiedObject` instance if it was already created. Otherwise, objects will be created only when first needed.

    #### Use case

    This method is typically used together with `getAuthorityCodes()` for altering the iteration order on the basis of authority codes. If the specified `codes` sequence contains the same elements as the ones in the array returned by `getAuthorityCodes()` but in a different order, then this method just sets the new ordering.
    Parameters:
      `codes` - the authority codes of identified objects to store in this set.
    See Also:
      - `addAuthorityCode(String)`

  - ### addAuthorityCode

    public void addAuthorityCode(String code)
    Ensures that this collection contains an object for the specified authority code. If this collection does not contain any element for the given code, then this method will instantiate an `IdentifiedObject` for the given code only when first needed. Otherwise, this collection is unchanged.
    Parameters:
      `code` - the code authority code of the `IdentifiedObject` to include in this set.

  - ### add

    public boolean add(T object)
    Ensures that this collection contains the specified object. This collection does not allow multiple objects for the same authority code. If this collection already contains an object using the same authority code as the given object, then the old object is replaced by the new one regardless of whether the objects themselves are equal or not.
    Specified by:
      `add` in interface `Collection<T extends IdentifiedObject>`
    Specified by:
      `add` in interface `Set<T extends IdentifiedObject>`
    Overrides:
      `add` in class `AbstractCollection<T extends IdentifiedObject>`
    Parameters:
      `object` - the object to add to the set.
    Returns:
      `true` if this set changed as a result of this call.
    See Also:
      - `getAuthorityCode(IdentifiedObject)`

  - ### contains

    public boolean contains(Object object)
    Returns `true` if this collection contains the specified `IdentifiedObject`.
    Specified by:
      `contains` in interface `Collection<T extends IdentifiedObject>`
    Specified by:
      `contains` in interface `Set<T extends IdentifiedObject>`
    Overrides:
      `contains` in class `AbstractCollection<T extends IdentifiedObject>`
    Parameters:
      `object` - the `IdentifiedObject` to test for presence in this set.
    Returns:
      `true` if the given object is presents in this set.
    Throws:
      `ClassCastException` - if the given object is non-null and not an instance of `<T>`.

  - ### remove

    public boolean remove(Object object)
    Removes the specified `IdentifiedObject` from this collection, if it is present.
    Specified by:
      `remove` in interface `Collection<T extends IdentifiedObject>`
    Specified by:
      `remove` in interface `Set<T extends IdentifiedObject>`
    Overrides:
      `remove` in class `AbstractCollection<T extends IdentifiedObject>`
    Parameters:
      `object` - the `IdentifiedObject` to remove from this set.
    Returns:
      `true` if this set changed as a result of this call.
    Throws:
      `ClassCastException` - if the given object is non-null and not an instance of `<T>`.

  - ### removeAll

    public boolean removeAll(Collection<?> collection)
    Removes from this collection all of its elements that are contained in the specified collection.
    Specified by:
      `removeAll` in interface `Collection<T extends IdentifiedObject>`
    Specified by:
      `removeAll` in interface `Set<T extends IdentifiedObject>`
    Overrides:
      `removeAll` in class `AbstractSet<T extends IdentifiedObject>`
    Parameters:
      `collection` - the `IdentifiedObject`s to remove from this set.
    Returns:
      `true` if this set changed as a result of this call.
    Throws:
      `ClassCastException` - if the given collection contains an object which is not an instance of `<T>`.

  - ### iterator

    public Iterator<T> iterator() throws BackingStoreException
    Returns an iterator over the objects in this set. If the iteration encounter any kind of `FactoryException` other than `NoSuchIdentifierException`, then the exception will be re-thrown as an unchecked `BackingStoreException`.

    This iterator is not thread safe – iteration should be done in a single thread. However, the iterator is robust to concurrent changes in `IdentifiedObjectSet` during iteration.

    Specified by:
      `iterator` in interface `Collection<T extends IdentifiedObject>`
    Specified by:
      `iterator` in interface `Iterable<T extends IdentifiedObject>`
    Specified by:
      `iterator` in interface `Set<T extends IdentifiedObject>`
    Specified by:
      `iterator` in class `AbstractCollection<T extends IdentifiedObject>`
    Returns:
      an iterator over all `IdentifiedObject` instances in this set, in insertion order.
    Throws:
      `BackingStoreException` - if an error occurred while creating the iterator.

  - ### resolve

    public void resolve(int n) throws FactoryException
    Ensures that the n first objects in this set are created. This method can be invoked for making sure that the underlying factory is really capable to create at least one object. `FactoryException` (except the ones accepted as recoverable failures) are thrown as if they were never wrapped into `BackingStoreException`.
    Parameters:
      `n` - the number of object to resolve. If this number is equal or greater than `size()`, then this method ensures that all `IdentifiedObject` instances in this collection are created.
    Throws:
      `FactoryException` - if an object creation failed.

  - ### getAuthorityCode

    protected String getAuthorityCode(T object)
    Returns the identifier for the specified object. The default implementation takes the first of the following identifier which is found:
    1. An identifier allocated by the authority given by `factory.getAuthority()`.
    2. The first object identifier, regardless its authority.
    3. The first object name, regardless its authority.
    Subclasses may override this method if they want to use a different identifiers.
    Parameters:
      `object` - the object for which to get the authority code.
    Returns:
      the authority code of the given identified object.
    Throws:
      `BackingStoreException` - if an error occurred while fetching the authority code.

  - ### createObject

    protected T createObject(String code) throws FactoryException
    Creates an object for the specified authority code. This method is invoked during the iteration process if an object was not already created.
    Parameters:
      `code` - the code for which to create the identified object.
    Returns:
      the identified object created from the given code.
    Throws:
      `FactoryException` - if the object creation failed.
      `ClassCastException` - if the object created from the given object is not an instance of `<T>`.

  - ### isRecoverableFailure

    protected boolean isRecoverableFailure(FactoryException exception)
    Returns `true` if the specified exception should be handled as a recoverable failure. This method is invoked during the iteration process if the factory failed to create some objects. If this method returns `true` for the given exception, then the exception will be logged at `Level​.WARNING`. If this method returns `false`, then the exception will be re-thrown as a `BackingStoreException`.

    The default implementation applies the following rules:

    - If `NoSuchAuthorityCodeException`, returns `false` since failure to find a code declared in the collection would be an inconsistency. Note that this exception is a subtype of `NoSuchIdentifierException`, so it must be tested before the last case below.
    - If `NoSuchIdentifierException`, returns `true` because this exception is caused by an attempt to create a parameterized transform for an unimplemented operation.
    - If `MissingFactoryResourceException`, returns `true`.
    - Otherwise returns `false`.
    Parameters:
      `exception` - the exception that occurred while creating an object.
    Returns:
      `true` if the given exception should be considered recoverable, or `false` if it should be considered fatal.