Module jdk.dynalink
Package jdk.dynalink

## Class CompositeOperation

- java.lang.Object
- - jdk.dynalink.CompositeOperation

All Implemented Interfaces:
  Operation

    public final class CompositeOperation
    extends Object
    implements Operation

Describes an operation that is composed of at least two other operations. The component operations are treated as alternatives to each other in order of preference. The semantics of the composite operation is "first successful". That is, a composite of `GET_PROPERTY|GET_ELEMENT:color` should be interpreted as get the property named "color" on the object, but if the property does not exist, then get the collection element named "color" instead.

Composite operations are helpful in implementation of languages that don't distinguish between one or more of the property, method, and element namespaces, or when expressing operations against objects that can be considered both ordinary objects and collections, e.g. Java `Map` objects. A composite operation `GET_PROPERTY|GET_ELEMENT:empty` against a Java map will always match the `Map.isEmpty()` property, but `GET_ELEMENT|GET_PROPERTY:empty` will actually match a map element with key `"empty"` if the map contains that key, and only fall back to the `isEmpty()` property getter if the map does not contain the key. If the source language mandates this semantics, it can be easily achieved using composite operations.

Even if the language itself doesn't distinguish between some of the namespaces, it can be helpful to map different syntaxes to different compositions. E.g. the source expression `obj.color` could map to `GET_PROPERTY|GET_ELEMENT|GET_METHOD:color`, but a different source expression that looks like collection element access `obj[key]` could be expressed instead as `GET_ELEMENT|GET_PROPERTY|GET_METHOD`. Finally, if the retrieved value is subsequently called, then it makes sense to bring `GET_METHOD` to the front of the list: the getter part of the source expression `obj.color()` should be `GET_METHOD|GET_PROPERTY|GET_ELEMENT:color` and the one for `obj[key]()` should be `GET_METHOD|GET_ELEMENT|GET_PROPERTY`.

The elements of a composite operation can not be composites or named operations, but rather simple operations such are elements of `StandardOperation`. A composite operation itself can serve as the base operation of a named operation, though; a typical way to construct e.g. the `GET_ELEMENT|GET_PROPERTY:empty` from above would be:

     Operation getElementOrPropertyEmpty = new NamedOperation(
         new CompositeOperation(
             StandardOperation.GET_ELEMENT,
             StandardOperation.GET_PROPERTY),
         "empty");

Not all compositions make sense. Typically, any combination in any order of standard getter operations `GET_PROPERTY`, `GET_ELEMENT`, and `GET_METHOD` make sense, as do combinations of `SET_PROPERTY` and `SET_ELEMENT`; other standard operations should not be combined. The constructor will allow any combination of operations, though.

### Constructor Summary

Constructors
Constructor and Description
`CompositeOperation(Operation... operations)` Constructs a new composite operation.

### Method Summary

All Methods Static Methods Instance Methods Concrete Methods
`boolean` `contains(Operation operation)` Returns true if this composite operation contains an operation equal to the specified operation.
`static boolean` `contains(Operation composite, Operation operation)` Returns true if the specified potentially composite operation is a `CompositeOperation` and contains an operation equal to the specified operation.
`boolean` `equals(Object obj)` Returns true if the other object is also a composite operation and their component operations are equal.
`Operation` `getOperation(int i)` Returns the i-th component operation in this composite operation.
`int` `getOperationCount()` Returns the number of component operations in this composite operation.
`Operation[]` `getOperations()` Returns the component operations in this composite operation.
`static Operation[]` `getOperations(Operation op)` Returns the components of the passed operation if it is a composite operation, otherwise returns an array containing the operation itself.
`int` `hashCode()` Returns the hash code of this composite operation.
`String` `toString()` Returns the string representation of this composite operation.

### Methods inherited from class java.lang.Object

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

### Constructor Detail

#### CompositeOperation

    public CompositeOperation(Operation... operations)

Constructs a new composite operation.

Parameters:
  `operations` - the components for this composite operation. The passed array will be cloned.
Throws:
  `IllegalArgumentException` - if less than two components are specified, or any component is itself a `CompositeOperation` or a `NamedOperation`.
  `NullPointerException` - if either the operations array or any of its elements are `null`.

### Method Detail

#### getOperations

    public Operation[] getOperations()

Returns the component operations in this composite operation. The returned array is a copy and changes to it don't have effect on this object.

Returns:
  the component operations in this composite operation.

#### getOperationCount

    public int getOperationCount()

Returns the number of component operations in this composite operation.

Returns:
  the number of component operations in this composite operation.

#### getOperation

    public Operation getOperation(int i)

Returns the i-th component operation in this composite operation.

Parameters:
  `i` - the operation index
Returns:
  the i-th component operation in this composite operation.
Throws:
  `IndexOutOfBoundsException` - if the index is out of range.

#### contains

    public boolean contains(Operation operation)

Returns true if this composite operation contains an operation equal to the specified operation.

Parameters:
  `operation` - the operation being searched for. Must not be null.
Returns:
  true if the if this composite operation contains an operation equal to the specified operation.

#### equals

    public boolean equals(Object obj)

Returns true if the other object is also a composite operation and their component operations are equal.

Overrides:
  `equals` in class `Object`
Parameters:
  `obj` - the object to compare to
Returns:
  true if this object is equal to the other one, false otherwise.
See Also:
  `Object.hashCode()`, `HashMap`

#### hashCode

    public int hashCode()

Returns the hash code of this composite operation. Defined to be equal to `java.util.Arrays.hashCode(operations)`.

Overrides:
  `hashCode` in class `Object`
Returns:
  a hash code value for this object.
See Also:
  `Object.equals(java.lang.Object)`, `System.identityHashCode(java.lang.Object)`

#### toString

    public String toString()

Returns the string representation of this composite operation. Defined to be the `toString` of its component operations, each separated by the vertical line character (e.g. `"GET_PROPERTY|GET_ELEMENT"`).

Overrides:
  `toString` in class `Object`
Returns:
  the string representation of this composite operation.

#### getOperations

    public static Operation[] getOperations(Operation op)

Returns the components of the passed operation if it is a composite operation, otherwise returns an array containing the operation itself. This allows for returning an array of component even if it is not known whether the operation is itself a composite (treating a non-composite operation as if it were a single-element composite of itself).

Parameters:
  `op` - the operation whose components are retrieved.
Returns:
  if the passed operation is a composite operation, returns its `getOperations()`, otherwise returns the operation itself.

#### contains

    public static boolean contains(Operation composite,
                                   Operation operation)

Returns true if the specified potentially composite operation is a `CompositeOperation` and contains an operation equal to the specified operation. If `composite` is not a `CompositeOperation`, then the two operations are compared for equality.

Parameters:
  `composite` - the potentially composite operation. Must not be null.
  `operation` - the operation being searched for. Must not be null.
Returns:
  true if the if the passed operation is a `CompositeOperation` and contains a component operation equal to the specified operation, or if it is not a `CompositeOperation` and is equal to `operation`.