org.eclipse.handly.model.impl.support

## Interface IElementImplSupport

- All Superinterfaces:
    IElement, IElementImpl, IElementImplExtension, IModelManager.Provider
  All Known Subinterfaces:
    ISourceConstructImplSupport, ISourceElementImplSupport, ISourceFileImplSupport
  All Known Implementing Classes:
    BaseSourceFile, Element, FsSourceFile, SourceConstruct, SourceFile, WorkspaceSourceFile

      public interface IElementImplSupport
      extends IElementImplExtension, IModelManager.Provider

  A "trait-like" interface providing a skeletal implementation of `IElementImplExtension` to minimize the effort required to implement that interface. Clients may implement ("mix in") this interface directly or extend `Element`.

  In general, the members first defined in this interface are not intended to be referenced outside the subtype hierarchy.

  Restriction:
    This interface is not intended to be extended by clients.

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from interface org.eclipse.handly.model.impl.IElementImplExtension

      `IElementImplExtension.CloseHint`

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static Property<java.util.Map<IElement,java.lang.Object>>` | `NEW_ELEMENTS` A map containing element handle/body relationships.
    `static java.lang.Object` | `NO_BODY` Special-purpose value for the `body` argument of the `toStringBody_(StringBuilder, Object, IContext)` method; indicates that information about the body is not relevant.

    - ### Fields inherited from interface org.eclipse.handly.model.impl.IElementImplExtension

      `CLOSE_HINT, FORCE_OPEN`

  - ### Method Summary

    All Methods Instance Methods Abstract Methods Default Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `buildStructure_(IContext context, org.eclipse.core.runtime.IProgressMonitor monitor)` Creates and initializes bodies for this element and for each non-`openable` child element (and their non-openable children, recursively).
    `default boolean` | `canEqual_(java.lang.Object obj)` Returns whether this element can equal the given object.
    `default void` | `close_(IContext context)` Closes this element if, and only if, the current state of this element permits closing according to options specified in the given context.
    `default boolean` | `defaultEquals_(java.lang.Object obj)` A default implementation of `IElement.equals(Object)` cannot be provided in an interface, but clients can implement `equals` by delegating to this default method.
    `default int` | `defaultHashCode_()` A default implementation of `IElement.hashCode()` cannot be provided in an interface, but clients can implement `hashCode` by delegating to this default method.
    `default boolean` | `exists_()` Returns whether this element exists in the model.
    `default java.lang.Object` | `findBody_()` Returns the cached body for this element, or `null` if none.
    `default IElement[]` | `getChildrenFromBody_(java.lang.Object body)` Given a body for this element, returns the immediate children.
    `default ElementManager` | `getElementManager_()` Returns the element manager for this element.
    `default IModel` | `getModel_()` Returns the model that owns this element.
    `default boolean` | `isOpenable_()` Returns whether this element is "openable".
    `default org.eclipse.core.runtime.CoreException` | `newDoesNotExistException_()` Returns a new instance of generic "element does not exist" exception.
    `default java.lang.Object` | `open_(IContext context, org.eclipse.core.runtime.IProgressMonitor monitor)` Ensures that this element is open, i.e., it exists and is present in the body cache.
    `default void` | `openParent_(IContext context, org.eclipse.core.runtime.IProgressMonitor monitor)` Opens the parent element if necessary.
    `default java.lang.Object` | `peekAtBody_()` Returns the cached body for this element without disturbing cache ordering, or `null` if none.
    `default void` | `remove_(IContext context)` Removes this element from the body cache according to options specified in the given context.
    `default void` | `removing_(java.lang.Object body)` Informs this element that its body is going to be removed from the body cache.
    `default java.lang.String` | `toString_(IContext context)` Returns a string representation of this element in a form suitable for debugging purposes.
    `default void` | `toStringAncestors_(java.lang.StringBuilder builder, IContext context)`
    `default void` | `toStringBody_(java.lang.StringBuilder builder, java.lang.Object body, IContext context)`
    `default void` | `toStringChildren_(java.lang.StringBuilder builder, java.lang.Object body, IContext context)`
    `default void` | `toStringName_(java.lang.StringBuilder builder, IContext context)`
    `void` | `validateExistence_(IContext context)` Validates that this element may be "opened", i.e., begin existence in the model.

    - ### Methods inherited from interface org.eclipse.handly.model.impl.IElementImplExtension

      `close_, getBody_, getBody_, getChildren_`

    - ### Methods inherited from interface org.eclipse.handly.model.impl.IElementImpl

      `equalsAndSameParentChain_, getChildrenOfType_, getHandleMemento_, getLocationUri_, getName_, getParent_, getResource_, getRoot_, toDisplayString_`

    - ### Methods inherited from interface org.eclipse.handly.model.IElement

      `equals, hashCode`

    - ### Methods inherited from interface org.eclipse.handly.model.impl.support.IModelManager.Provider

      `getModelManager_`

- - ### Field Detail

    - #### NEW_ELEMENTS

          static final Property<java.util.Map<IElement,java.lang.Object>> NEW_ELEMENTS

      A map containing element handle/body relationships.
      See Also:
        `buildStructure_(IContext, IProgressMonitor)`

    - #### NO_BODY

          static final java.lang.Object NO_BODY

      Special-purpose value for the `body` argument of the `toStringBody_(StringBuilder, Object, IContext)` method; indicates that information about the body is not relevant.

  - ### Method Detail

    - #### defaultHashCode_

          default int defaultHashCode_()

      A default implementation of `IElement.hashCode()` cannot be provided in an interface, but clients can implement `hashCode` by delegating to this default method.

      By default, the hash code for an element is a combination of hash codes for its name and its parent element. This method is specialized in `ISourceConstructImplSupport` to include the element's occurrence count, and in `ISourceFileImplSupport` to return the hash code for the underlying file object, if there is one. This method is not intended to be replaced by clients; if necessary, clients should override `hashCode` directly.

      Returns:
        a hash code value

    - #### defaultEquals_

          default boolean defaultEquals_(java.lang.Object obj)

      A default implementation of `IElement.equals(Object)` cannot be provided in an interface, but clients can implement `equals` by delegating to this default method.

      By default, two elements that implement this interface are equal if they are identical or if they `can equal` each other and do have equal names and equal parents. This method is specialized in `ISourceConstructImplSupport` and `ISourceFileImplSupport` to also compare occurrence counts and underlying file objects respectively. This method is not intended to be replaced by clients; if necessary, clients should override `equals` directly.

      Parameters:
        `obj` - the object with which to compare
      Returns:
        `true` if this element is equal to the given object, and `false` otherwise

    - #### canEqual_

          default boolean canEqual_(java.lang.Object obj)

      Returns whether this element can equal the given object. If this method returns `false`, the `equals` method must also return `false` for the same argument object.

      This implementation compares run-time classes of the objects for equality; as such, it does not allow creating a subclass whose instances can equal superclass instances. Clients may provide their own implementation for this method and use a less discriminating technique such as `instanceof` check.

      For details, see https://www.artima.com/pins1ed/object-equality.html#28.2, Pitfall #4.

      Parameters:
        `obj` - not `null`
      Returns:
        `true` if this element can equal the given object, and `false` otherwise

    - #### getModel_

          default IModel getModel_()

      Returns the model that owns this element. This is a handle-only method.

      This implementation returns `getModelManager_().getModel()`.

      Specified by:
        `getModel_` in interface `IElementImpl`
      Returns:
        the element's model (never `null`)

    - #### getElementManager_

          default ElementManager getElementManager_()

      Returns the element manager for this element. The manager must be shared between all elements of a Handly-based model. Typical implementations would answer a model-specific singleton. This is a handle-only method.

      This implementation returns `getModelManager_().getElementManager()`.

      Returns:
        the element manager for this element (never `null`)

    - #### getChildrenFromBody_

          default IElement[] getChildrenFromBody_(java.lang.Object body)

      Given a body for this element, returns the immediate children.

      This implementation returns `((Body)body).`getChildren()``.

      Specified by:
        `getChildrenFromBody_` in interface `IElementImplExtension`
      Parameters:
        `body` - a body for this element (not `null`)
      Returns:
        the immediate children (never `null`). Clients must not modify the returned array.

    - #### findBody_

          default java.lang.Object findBody_()

      Description copied from interface: `IElementImplExtension`
      Returns the cached body for this element, or `null` if none.
      Specified by:
        `findBody_` in interface `IElementImplExtension`
      Returns:
        the cached body for this element, or `null` if none

    - #### peekAtBody_

          default java.lang.Object peekAtBody_()

      Description copied from interface: `IElementImplExtension`
      Returns the cached body for this element without disturbing cache ordering, or `null` if none.
      Specified by:
        `peekAtBody_` in interface `IElementImplExtension`
      Returns:
        the cached body for this element, or `null` if none

    - #### exists_

          default boolean exists_()

      Returns whether this element exists in the model.

      Handles may or may not be backed by an actual element. Handles that are backed by an actual element are said to "exist".

      This implementation returns `true` if there is a cached body for this element, and `false` if this element has a parent and the parent does not exist; otherwise, it invokes `validateExistence_` to determine the result.

      Specified by:
        `exists_` in interface `IElementImpl`
      Returns:
        `true` if this element exists in the model, and `false` if this element does not exist

    - #### validateExistence_

          void validateExistence_(IContext context)
                           throws org.eclipse.core.runtime.CoreException

      Validates that this element may be "opened", i.e., begin existence in the model. For example, a necessary condition for element existence might be that the underlying resource exists.

      Note that ancestor elements may or may not exist; this method need not explicitly verify their existence.

      Parameters:
        `context` - the operation context (not `null`)
      Throws:
        `org.eclipse.core.runtime.CoreException` - if this element shall not exist
      See Also:
        `newDoesNotExistException_()`

    - #### newDoesNotExistException_

          default org.eclipse.core.runtime.CoreException newDoesNotExistException_()

      Returns a new instance of generic "element does not exist" exception. The exception's message identifies the non-existing element without giving any details about the reason for nonexistence.
      Returns:
        a new "element does not exist" exception (never `null`)

    - #### open_

          default java.lang.Object open_(IContext context,
                                         org.eclipse.core.runtime.IProgressMonitor monitor)
                                  throws org.eclipse.core.runtime.CoreException

      Ensures that this element is open, i.e., it exists and is present in the body cache. Returns the cached body for this element.

      Implementations are encouraged to support the following standard options, which may be specified in the given context:

      - `IElementImplExtension.FORCE_OPEN` - Indicates whether to forcibly reopen this element if it is already open (i.e., already present in the body cache).

      This implementation attempts to `open` the parent element first. Then, if this element is `openable` and is `permitted` to open, invokes `buildStructure_(IContext, IProgressMonitor)` with an appropriately augmented context, acquires the element manager lock, updates the body cache with the built structure, and releases the lock. When this element is already open, the update may involve closing existing children or do nothing at all, depending on the value of `FORCE_OPEN`. If this element is not openable and the openable parent did not create a body for this element, this implementation throws a `newDoesNotExistException_()`.

      Specified by:
        `open_` in interface `IElementImplExtension`
      Parameters:
        `context` - the operation context (not `null`)
        `monitor` - a progress monitor, or `null` if progress reporting is not desired. The caller must not rely on `IProgressMonitor.done()` having been called by the receiver
      Returns:
        the cached body for this element (never `null`)
      Throws:
        `org.eclipse.core.runtime.CoreException` - if this element does not exist or if an exception occurs while accessing its corresponding resource

    - #### openParent_

          default void openParent_(IContext context,
                                   org.eclipse.core.runtime.IProgressMonitor monitor)
                            throws org.eclipse.core.runtime.CoreException

      Opens the parent element if necessary.

      This method is called internally; it is not intended to be invoked by clients.

      This implementation attempts to `open` the parent element if it supports `IElementImplExtension` and is not already open.

      Parameters:
        `context` - the operation context (never `null`)
        `monitor` - a progress monitor (never `null`). The caller must not rely on `IProgressMonitor.done()` having been called by the receiver
      Throws:
        `org.eclipse.core.runtime.CoreException` - if an exception occurs while opening this element's parent
        `org.eclipse.core.runtime.OperationCanceledException` - if this method is canceled
      See Also:
        `open_(IContext, IProgressMonitor)`

    - #### isOpenable_

          default boolean isOpenable_()

      Returns whether this element is "openable". Openable elements know how to `build` their structure and can be `opened` one by one. In particular, there is no need to open an openable child when opening its parent. Non-openable elements rely on the openable parent to build their structure. Opening of a parent element opens all non-openable children at once.

      This implementation returns `true`. Non-openable elements must override this method and return `false`.

      Returns:
        `true` if this element is openable, and `false` otherwise

    - #### buildStructure_

          void buildStructure_(IContext context,
                               org.eclipse.core.runtime.IProgressMonitor monitor)
                        throws org.eclipse.core.runtime.CoreException

      Creates and initializes bodies for this element and for each non-`openable` child element (and their non-openable children, recursively). Uses the `NEW_ELEMENTS` map in the given context to associate the created bodies with their respective elements.

      Note that this method does not make sense and must not be called for non-openable elements -- they rely on the openable parent to build their structure.

      Parameters:
        `context` - the operation context (not `null`)
        `monitor` - a progress monitor (not `null`). The caller must not rely on `IProgressMonitor.done()` having been called by the receiver
      Throws:
        `org.eclipse.core.runtime.CoreException` - if the structure could not be determined
        `org.eclipse.core.runtime.OperationCanceledException` - if this method is canceled

    - #### close_

          default void close_(IContext context)

      Closes this element if, and only if, the current state of this element permits closing according to options specified in the given context.

      Closing of an element removes its body from the body cache. In general, closing of a parent element also closes its children. If the current state of an open child element does not permit closing, the child element remains open, which generally does not prevent its parent from closing. Closing of an element which is not open has no effect.

      Implementations are encouraged to support the following standard options, which may be specified in the given context:

      - `IElementImplExtension.CLOSE_HINT` - Closing hint.

      After checking that the current state of this element permits closing, this implementation invokes `remove_(IContext)` to actually close this element.

      Specified by:
        `close_` in interface `IElementImplExtension`
      Parameters:
        `context` - the operation context (not `null`)

    - #### remove_

          default void remove_(IContext context)

      Removes this element from the body cache according to options specified in the given context. In general, not only removes the cached body for this element but also attempts to close this element's children. Does nothing if the cache contained no body for this element.

      This is a low-level operation, which removes this element's body and thus closes this element even if the current state of this element does not permit closing. Consider using a higher-level `close_(IContext)` method.

      If there is a cached body for this element, this implementation invokes `removing_(Object)` method to notify this element of the upcoming removal of its body, calls `close_(of(CLOSE_HINT, PARENT_CLOSING))` for each of this element's children, then removes the cached body for this element, all while holding the element manager lock.

      Parameters:
        `context` - the operation context (not `null`)

    - #### removing_

          default void removing_(java.lang.Object body)

      Informs this element that its body is going to be removed from the body cache. This method is called under the element manager lock.

      This method is called internally; it is not intended to be invoked by clients.

      Parameters:
        `body` - the cached body for this element (never `null`)

    - #### toString_

          default java.lang.String toString_(IContext context)

      Description copied from interface: `IElementImpl`
      Returns a string representation of this element in a form suitable for debugging purposes. Clients can influence the result with format options specified in the given context; unrecognized options are ignored and an empty context is permitted.

      Implementations are encouraged to support common options defined in `ToStringOptions` and interpret the `FORMAT_STYLE` as follows:

      - `FULL` - A full representation that lists ancestors and children.
      - `LONG` - A long representation that lists children but not ancestors.
      - `MEDIUM` - A compact representation that lists ancestors but not children.
      - `SHORT` - A minimal representation that does not list ancestors or children.
      Specified by:
        `toString_` in interface `IElementImpl`
      Parameters:
        `context` - not `null`
      Returns:
        a string representation of this element (never `null`)

    - #### toStringAncestors_

          default void toStringAncestors_(java.lang.StringBuilder builder,
                                          IContext context)

    - #### toStringChildren_

          default void toStringChildren_(java.lang.StringBuilder builder,
                                         java.lang.Object body,
                                         IContext context)

    - #### toStringBody_

          default void toStringBody_(java.lang.StringBuilder builder,
                                     java.lang.Object body,
                                     IContext context)

    - #### toStringName_

          default void toStringName_(java.lang.StringBuilder builder,
                                     IContext context)

Copyright (c) 2014, 2020 1C-Soft LLC and others. Made available under the Eclipse Public License 2.0