therian is implemented as an open-ended mechanism for executing type-safe Operations defined in Java. The core Operations are the reason we’re here:
Represents type conversion from a readable SOURCE Position to a writable TARGET Position. A successful evaluation result is a TARGET instance, but the value is also set upon the target position, if specified:
Convert.to(targetPosition, sourcePosition); Convert.to(targetType, sourcePosition);
A Convert Operation is usually supported by a Converter subclass.
therian defines a number of supporting Operations which are used to assist in the implementation of the more central Operations:
Requests the addition of a readable SOURCE Position to a readable TARGET “container” position, in the nature of element to Collection. This Operation’s Boolean result indicates whether successful execution resulted in a modification to the TARGET.
Add.to(targetPosition, sourcePosition);
Requests the addition of a readable SOURCE “container” Position’s content to a readable TARGET “container” position. Like Add, this Operation’s Boolean result indicates whether successful execution resulted in a modification to the TARGET.
AddAll.to(targetPosition, sourcePosition);
Requests the element Type of a readable “container” Position or other org.apache.commons.lang3.reflect.Typed instance. therian provides built-in support for:
An unrecognized type will be treated as a singleton container; i.e. it will return its own type. As always custom Operators can be supplied that understand how to get the element Type of any custom type.
GetElementType.of(position); GetElementType.of(typed);
Checks whether the value of a readable Position is immutable. Specifically this is useful when executing a deep Copy Operation; by default, the base Copier class supports the notion that a Copy to a TARGET Position with an immutable value is rejected. This follows from the notion that a Copy Operation has the implicit intent of mutating its TARGET. therian’s ConvertingCopier provides the ability, in these cases, to fall back to a Convert Operation, enforcing the so-called “principle of least surprise.” therian ships with the DefaultImmutableChecker which detects the immutability of:
Clients can provide custom ImmutableChecker extensions to inform therian which custom types must be considered immutable.
ImmutableCheck.of(readablePosition)
Gets the size of a readable “container” Position as Integer. therian is equipped to take the sizes of:
null objects have size 0; other objects not supported by some Size Operator are considered singletons and have size 1. As usual, custom Size Operators can handle custom types.
Size.of(readablePosition);
Therian is open-ended and can be used to create custom Operation/Operator combinations. The most important thing to know when creating a custom Operation is that therian must be able to discern its Type parameter assignments at runtime, a feature not normally available with parameterized Java types. To support this requirement, an Operation subclass should provide, for each declared type variable V, a corresponding method taking no parameters, returning Typed<V>, and annotated with @BindTypeVariable. This will allow therian to detect the type bindings of the Operation and thus locate its supporting Operators.