Package com.zfabrik.work

## Class WorkUnit

- java.lang.Object
- - com.zfabrik.work.WorkUnit

- All Implemented Interfaces:
    `java.lang.AutoCloseable`

      public final class WorkUnit
      extends java.lang.Object
      implements java.lang.AutoCloseable

  A Work Unit comprises resources that are bound to some logical work process. A work unit may be transactional or immediate. Resources are encouraged to register with the work unit. In order to orderly use the work unit mechanism, it is required to initialize and later close a work unit by using it as an `AutoCloseable` or explicitly:

       try (WorkUnit.initCurrent()) {
       ...
       }

  or

       WorkUnit.initCurrent();
       try {
       ...
       } finally {
          WorkUnit.closeCurrent();
       }

  This pattern is implemented by the `work(Callable)` method and its sibling. The application thread pool implementation uses this pattern, so that in general it is not necessary to implement it individually, except work has to be done in a Timer Thread and will not be associated with the Application Thread Pool (which is the preferred method!). See also `IThreadPool.executeAs(Runnable, boolean)`. On the current thread however, after any completion, i.a. after a call to close() we release the work unit association. This is for resource consumption reasons (and not to hold on to something that should be collectable) but also so that we can normally see whether a thread has been setup correctly during getCurrent(). We want to know (by exception) if a thread is querying for a work unit although it has not been properly initialized - which in turn indicates that it will most likely not be completed properly either.
  Author:
    Henning

- - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `static void` | `attach​(WorkUnit unit)` | attaches a given work unit with the current thread.
    `void` | `bindResource​(java.lang.String key, IWorkResource resource)` | bind and, if unit is stateful, begin resource
    `void` | `close()` | Close work unit.
    `static void` | `closeCurrent()` | Closes the current work unit (if any).
    `void` | `commit()` | Commit work unit.
    `static void` | `commitCurrent()` | commits the current work unit (if any)
    `static WorkUnit` | `detach()` | Detaches current work unit (if any) from the current thread
    `static WorkUnit` | `getCurrent()` | gets current work unit.
    `IWorkResource` | `getResource​(java.lang.String key)` | returns a named work resource
    `boolean` | `getRollbackOnly()` | Gets whether this unit is to be rolled back on close
    `static boolean` | `getRollbackOnlyCurrent()` | Gets whether the current work unit, if any, is to be rolled back on close.
    `static WorkUnit` | `initCurrent()` | initializes a work unit orderly on a thread join the current, if present.
    `static WorkUnit` | `queryCurrent()` | queries current work unit but will not instantiate one.
    `void` | `rollback()` | Rollback the work unit.
    `static void` | `rollBackCurrent()` | rolls back the current work unit (if any)
    `void` | `setRollbackOnly()` | Sets this unit to be rolled back on close.
    `static void` | `setRollbackOnlyCurrent()` | Sets the current work unit, if any, to be rolled back on close.
    `static <T,​E extends java.lang.Exception> T` | `supply​(ThrowingSupplier<T,​E> supplier)` | Execute a `ThrowingSupplier` within a complete work unit, incl.
    `IWorkResource` | `unbindResource​(java.lang.String key)` | unbind and if unit stateful rolls back resource
    `static void` | `work​(java.lang.Runnable r)` | Execute a runnable within a complete work unit, incl.
    `static <T> T` | `work​(java.util.concurrent.Callable<T> r)` | Execute a `Callable` within a complete work unit, incl.

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

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Method Detail

    - #### queryCurrent

          public static final WorkUnit queryCurrent()

      queries current work unit but will not instantiate one.

    - #### getCurrent

          public static final WorkUnit getCurrent()

      gets current work unit. If none bound, throw an exception as this indicates that this is a thread that has not orderly initialized the work unit.

    - #### commitCurrent

          public static void commitCurrent()

      commits the current work unit (if any)

    - #### rollBackCurrent

          public static void rollBackCurrent()

      rolls back the current work unit (if any)

    - #### initCurrent

          public static WorkUnit initCurrent()

      initializes a work unit orderly on a thread join the current, if present.

    - #### closeCurrent

          public static void closeCurrent()

      Closes the current work unit (if any). See `close()`.

    - #### setRollbackOnlyCurrent

          public static void setRollbackOnlyCurrent()

      Sets the current work unit, if any, to be rolled back on close. See `setRollbackOnly()`

    - #### getRollbackOnlyCurrent

          public static boolean getRollbackOnlyCurrent()

      Gets whether the current work unit, if any, is to be rolled back on close. See `getRollbackOnly()`.

    - #### detach

          public static WorkUnit detach()

      Detaches current work unit (if any) from the current thread

    - #### attach

          public static void attach​(WorkUnit unit)

      attaches a given work unit with the current thread. Will fail if there is one currently associated with the current thread.

    - #### commit

          public void commit()

      Commit work unit. If the work unit is set for rollback only however, the work unit will be rolled back. In the case of a commit, all enlisted resources will first receive a `IWorkResource.beforeCompletion(boolean)`. If during that phase the work unit is set to rollback only, a rollback is performed. See `rollback()`. Otherwise all resources receive a `IWorkResource.commit()` before all resources receive a `IWorkResource.afterCompletion(boolean)`.

    - #### rollback

          public void rollback()

      Rollback the work unit. For all enlisted resources a rollback and an after completion event will be triggered. See `IWorkResource` for more details.

    - #### setRollbackOnly

          public void setRollbackOnly()

      Sets this unit to be rolled back on close. That is, instead of committing a close will `rollback()`, if set to `true`

    - #### getRollbackOnly

          public boolean getRollbackOnly()

      Gets whether this unit is to be rolled back on close

    - #### close

          public void close()

      Close work unit. Note that a call to `initCurrent()` is either opening a new work unit of joining an existing. In the latter case, a use counter is incremented. A call to close only performs the actual close action, when the use counter is 1. Otherwise the use counter will simply be decreased. The actual close action is `rollback()`, if the work unit was set to rollback only (via `setRollbackOnly()` or `setRollbackOnlyCurrent()`) or `commit()` otherwise. In both cases, all enlisted resources will receive a close event. See `IWorkResource` for more details. If this work unit is the current work unit, it will be detached and there will be no current work unit anymore.
      Specified by:
        `close` in interface `java.lang.AutoCloseable`

    - #### bindResource

          public void bindResource​(java.lang.String key,
                                   IWorkResource resource)

      bind and, if unit is stateful, begin resource

    - #### unbindResource

          public IWorkResource unbindResource​(java.lang.String key)

      unbind and if unit stateful rolls back resource

    - #### getResource

          public IWorkResource getResource​(java.lang.String key)

      returns a named work resource

    - #### work

          public static void work​(java.lang.Runnable r)

      Execute a runnable within a complete work unit, incl. initialization and close. If the execution of the runnable throws an exception, the work unit will be rolled back.

    - #### supply

          public static <T,​E extends java.lang.Exception> T supply​(ThrowingSupplier<T,​E> supplier)
                                                                  throws E extends java.lang.Exception

      Execute a `ThrowingSupplier` within a complete work unit, incl. initialization and close. If the execution of the runnable throws an exception, the work unit will be rolled back.
      Throws:
        `E extends java.lang.Exception`

    - #### work

          public static <T> T work​(java.util.concurrent.Callable<T> r)
                            throws java.lang.Exception

      Execute a `Callable` within a complete work unit, incl. initialization and close. If the execution of the runnable throws an exception, the work unit will be rolled back.
      Throws:
        `java.lang.Exception`