Class TreeNodeChildren

java.lang.Object
java.util.AbstractCollection<TreeTable.Node>
org.apache.sis.metadata.TreeNodeChildren
All Implemented Interfaces:
Iterable<TreeTable.Node>, Collection<TreeTable.Node>

final class TreeNodeChildren extends AbstractCollection<TreeTable.Node>
The collection of children to be returned by TreeNode.getChildren(). This collection holds a reference to the metadata object at creation time; it does not track changes in parent.getUserObject().

Note on value existence policy

It is better to use this class with ValueExistencePolicy.NON_EMPTY in order to avoid code complication and surprising behavior of TreeNodeChildren.Iter.remove() operation. If the policy is set to another value, we need to keep the following aspects in mind:
  • When TreeNodeChildren.Iter.hasNext() finds a null or empty collection, it may needs to simulate a singleton with a null value.
  • In TreeNode.getUserObject(), we need the same check than above for simulating a singleton collection with a null value if the node is for the element at index 0.
Since:
0.3
Version:
1.1
  • Field Details

    • parent

      private final TreeNode parent
      The parent of the children to be returned by the iterator. Some useful information are available indirectly through this parent:
      See Also:
    • metadata

      final Object metadata
      The metadata object for which property values will be the elements of this collection. This is typically an AbstractMetadata instance, but not necessarily. Any type for which MetadataStandard.isMetadata(Class) returns true is okay.

      This field is a snapshot of the parent TreeNode.getUserObject() at creation time. This collection does not track changes in the reference returned by the above-cited getUserObject(). In other words, changes in the metadata object will be reflected in this collection, but if parent.getUserObject() returns a reference to another object, this change will not be reflected in this collection.

    • accessor

      final PropertyAccessor accessor
      The accessor to use for accessing the property names, types and values of the metadata object. This is given at construction time and shall be the same than the following code:
    • children

      private final TreeNode.Element[] children
      The children to be returned by this collection. All elements in this collection are initially null, then created by childAt(int, int) when first needed.

      Not all elements in this array will be returned by the iterator. The value needs to be verified for the ValueExistencePolicy.

    • titleProperty

      final int titleProperty
      Index of the property to write in the parent node instead of as a child. If a property has the same name than the parent property that contains it, we write its value in that parent property. For example, instead of: We simplify as:
      See Also:
    • modCount

      int modCount
      Modification count, incremented when the content of this collection is modified. This check is done on a best effort basis only, since we cannot not track the changes which are done independently in the metadata object.
  • Constructor Details

    • TreeNodeChildren

      TreeNodeChildren(TreeNode parent, Object metadata, PropertyAccessor accessor)
      Creates a collection of children for the specified metadata.
      Parameters:
      parent - the parent for which this node is an element.
      metadata - the metadata object for which property values will be the elements of this collection.
      accessor - the accessor to use for accessing the property names, types and values of the metadata object.
  • Method Details

    • getParentType

      final Class<?> getParentType()
      If a simple value should be associated to the parent node, returns the type of that value. Otherwise returns null.
    • getParentTitle

      final Object getParentTitle()
      If a simple value should be associated to the parent node, returns that value. Otherwise returns null.
    • setParentTitle

      final boolean setParentTitle(Object value)
      Sets the value associated to the parent node, if possible. This returned boolean tells whether the value has been written.
    • clearAt

      final void clearAt(int index)
      Clears the value at the given index. The given index is relative to the accessor indexing, not to this collection.

      The cleared elements may or may not be considered as removed, depending on the value policy. To check if the element shall be considered as removed (for example in order to update index), invoke isSkipped(value) after this method.

      Implementation note

      This method sets the property to null. This is not strictly correct for collections, since we should rather set the property to an empty collection. However, this approach would force us to check if the expected collection type is actually a list, a set or any other type. Passing null avoid the type check and is safe at least with SIS implementation. We may revisit later if this appears to be a problem with other implementations.
      Parameters:
      index - the index in the accessor (not the index in this collection).
    • valueAt

      final Object valueAt(int index)
      Returns the value at the given index. The given index is relative to the accessor indexing, not to this collection.
      Parameters:
      index - the index in the accessor (not the index in this collection).
      Returns:
      the value at the given index. May be null or a collection.
    • isCollectionOrMap

      final boolean isCollectionOrMap(int index)
      Returns true if the type at the given index is a collection or a map. The given index is relative to the accessor indexing, not to this collection.
      Implementation note: We do not test (value instanceof Collection) because the value could be any user's implementation. Nothing prevent users from implementing the collection interface even for singleton elements if they wish.
      Parameters:
      index - the index in the accessor (not the index in this collection).
      Returns:
      true if the value at the given index is a collection.
    • isSkipped

      final boolean isSkipped(Object value)
      Returns true if the give value shall be skipped by the iterators, according the value policy.
      Parameters:
      value - the value to test.
      Returns:
      true if the given value shall be skipped by the iterators.
    • childAt

      final TreeNode.Element childAt(int index, int subIndex)
      Returns the child at the given index, creating it if needed. The given index is relative to the accessor indexing, not to this collection.

      This method does not check if the child at the given index should be skipped. It is caller responsibility to do such verification before this method call.

      Parameters:
      index - the index in the accessor (not the index in this collection).
      subIndex - if the property at index is a collection, the index in that collection (not the index in this collection). Otherwise -1.
      Returns:
      the node to be returned by public API.
    • childCount

      final int childCount()
      Returns the maximal number of children. This is the number of all possible elements according the accessor, including skipped ones. This is not the collection size.
    • size

      public int size()
      Returns the number of elements in this collection, ignoring the skipped ones.
      Specified by:
      size in interface Collection<TreeTable.Node>
      Specified by:
      size in class AbstractCollection<TreeTable.Node>
    • isEmpty

      public boolean isEmpty()
      Returns true if this collection contains no elements. Invoking this method is more efficient than testing size() == 0 because this method does not iterate over all properties.
      Specified by:
      isEmpty in interface Collection<TreeTable.Node>
      Overrides:
      isEmpty in class AbstractCollection<TreeTable.Node>
    • clear

      public void clear()
      Clears all properties in the metadata object. Note that this collection will effectively by empty after this method call only if the value existence policy is NON_EMPTY, which is the default.
      Specified by:
      clear in interface Collection<TreeTable.Node>
      Overrides:
      clear in class AbstractCollection<TreeTable.Node>
    • iterator

      public Iterator<TreeTable.Node> iterator()
      Returns an iterator over the nodes in the collection of children.
      Specified by:
      iterator in interface Collection<TreeTable.Node>
      Specified by:
      iterator in interface Iterable<TreeTable.Node>
      Specified by:
      iterator in class AbstractCollection<TreeTable.Node>
    • add

      public boolean add(TreeTable.Node node) throws IllegalStateException
      Adds the given node to this list. This method fetches the object from TableColumn.VALUE and assigns it to the property identified by TableColumn.IDENTIFIER. All other columns are ignored.

      If the identified property is a collection, then this method adds the value to that collection. Otherwise the new value will be set only if the previous value is null, nil or empty.

      This method does not iterate explicitly through the children list, because adding a metadata object implicitly adds all its children.

      Specified by:
      add in interface Collection<TreeTable.Node>
      Overrides:
      add in class AbstractCollection<TreeTable.Node>
      Parameters:
      node - the node from which to get the values.
      Returns:
      true if the metadata changed as a result of this method call.
      Throws:
      NullPointerException - if the given node is null.
      IllegalArgumentException - if this list does not have a property for the node identifier.
      IllegalStateException - if a value already exists and no more value can be added for the node identifier.
      UnmodifiableMetadataException - if the property for the node identifier is read-only.
      ClassCastException - if the node value cannot be converted to the expected type.
      BackingStoreException - if the metadata implementation threw a checked exception.
    • add

      final boolean add(int index, Object value) throws IllegalStateException
      Implementation of add(TreeTable.Node), also invoked by TreeNode.NewChild. This method will attempt to convert the given value to the expected type.
      Parameters:
      index - the index in the accessor (not the index in this collection).
      value - the property value to add.
      Returns:
      true if the metadata changed as a result of this method call.
      Throws:
      IllegalStateException
    • toString

      public String toString()
      Returns a string representation of this collection for debugging purpose. This string representation uses one line per element instead of formatting everything on a single line.
      Overrides:
      toString in class AbstractCollection<TreeTable.Node>