Package org.eclipse.net4j.util.om.monitor

## Class SubMonitor

- java.lang.Object
- - org.eclipse.net4j.util.om.monitor.SubMonitor

- All Implemented Interfaces:
    `IProgressMonitor`, `IProgressMonitorWithBlocking`
  Direct Known Subclasses:
    `ProbingSubMonitor`

      public class SubMonitor
      extends java.lang.Object
      implements IProgressMonitorWithBlocking

  A `progress monitor` that uses a given amount of work ticks from a parent monitor. This is intended as a safer, easier-to-use alternative to `SubProgressMonitor`.

  Progress monitoring is generally quite invasive to the code that is monitored. At the same time progress monitoring itself is typically very hard to implement correctly. This class aims at reducing the invasiveness as much as possible while offering all the functionality needed to do the job right.

  The following aspects of this class help to keep the progress monitoring code short and nice and to avoid common monitoring mistakes:

  - It offers the full functionality of `SubMonitor`, which already makes progress monitoring a lot easier. Refer to the `SubMonitor` documentation or to this article for details and examples.
  - In addition to the `setWorkRemaining(int)` method it offers a `skipped(int)` method, which redistributes the remaining work according to the last skipped `worked(int)` or `newChild(int)` call rather than on the sum of all subsequent calls.
  - It reduces the need to specify `work` arguments by using the default value `1` with the overloaded `worked()`, `skipped()` and `newChild()` calls.
  - Basically all methods of this class can implicitly check for cancelation, thereby ensuring that the monitored code is always cancelable by the user without cluttering the code with repetitions of the following idiom:

        if (monitor.isCanceled())
        {
          throw new OperationCanceledException();
        }

    For details about automatic cancelation detection refer to `detectCancelation()`.
  - It is normally very challenging to find out how much time a program really spends in the different parts of the monitored methods or how often these parts get executed. Stepping through the program with a debugger obviously leads to distortion that renders the observations meaningless and adding extra code to measure a runtime scenario realistically is not nice from a maintenance point of view.

    As a solution to this problem this class offers the possibility to transparently instrument `SubMonitor` instances such that they automatically collect and report all kinds of statistics that may help to enhance the user experience. Sometimes it would even indicate to remove some progress monitoring because it turns out that almost no time is being spent in a particular part of the program. Another typical result from the analysis is the understanding of one time effects that might need special consideration.

    For details about this probing mode refer to `ProbingSubMonitor`.

  The following example shows how to monitor progress while recursing through a tree of folders:

      public void recurse(IContainer container, IProgressMonitor monitor) throws Exception
      {
        IResource[] members = container.members();

        SubMonitor progress = SubMonitor.convert(monitor, members.length).detectCancelation();
        progress.subTask(container.getFullPath().toString());

        for (IResource member : members)
        {
          if (member instanceof IContainer)
          {
            Thread.sleep(5);
            recurse((IContainer)member, progress.newChild());
          }
          else
          {
            progress.skipped();
          }
        }
      }

  Since:
    3.4
  Author:
    Eike Stepper

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class | Description
    --- | --- | ---
    `static class` | `SubMonitor.ProbingMode` | Enumerates the possible probing mode values `SubMonitor.ProbingMode.OFF`, `SubMonitor.ProbingMode.STANDARD` and `SubMonitor.ProbingMode.FULL`.

  - ### Field Summary

    Fields
    Modifier and Type | Field | Description
    --- | --- | ---
    `static int` | `DEFAULT_WORK` |
    `static int` | `SUPPRESS_ALL_LABELS` | May be passed as a flag to newChild.
    `static int` | `SUPPRESS_BEGINTASK` | May be passed as a flag to newChild.
    `static int` | `SUPPRESS_NONE` | May be passed as a flag to newChild.
    `static int` | `SUPPRESS_SETTASKNAME` | May be passed as a flag to newChild.
    `static int` | `SUPPRESS_SUBTASK` | May be passed as a flag to newChild.

    - ### Fields inherited from interface org.eclipse.core.runtime.IProgressMonitor

      `UNKNOWN`

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `void` | `beginTask​(java.lang.String name, int totalWork)` | Starts a new main task.
    `void` | `childDone()` |
    `void` | `clearBlocked()` |
    `static SubMonitor` | `convert​(IProgressMonitor monitor)` | Converts an unknown (possibly null) IProgressMonitor into a SubMonitor.
    `static SubMonitor` | `convert​(IProgressMonitor monitor, int work)` | Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks.
    `static SubMonitor` | `convert​(IProgressMonitor monitor, int work, SubMonitor.ProbingMode probingMode)` | Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks.
    `static SubMonitor` | `convert​(IProgressMonitor monitor, java.lang.String taskName, int work)` | Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks.
    `static SubMonitor` | `convert​(IProgressMonitor monitor, java.lang.String taskName, int work, SubMonitor.ProbingMode probingMode)` | Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks.
    `static SubMonitor` | `convert​(IProgressMonitor monitor, SubMonitor.ProbingMode probingMode)` | Converts an unknown (possibly null) IProgressMonitor into a SubMonitor.
    `SubMonitor` | `detectCancelation()` |
    `SubMonitor` | `detectCancelation​(boolean on)` |
    `void` | `done()` |
    `protected static boolean` | `eq​(java.lang.Object o1, java.lang.Object o2)` |
    `void` | `internalWorked​(double work)` |
    `boolean` | `isCanceled()` |
    `SubMonitor` | `newChild()` | Same as `newChild(1)`.
    `SubMonitor` | `newChild​(int totalWork)` | Creates a sub progress monitor that will consume the given number of ticks from the receiver.
    `SubMonitor` | `newChild​(int totalWork, int suppressFlags)` | Creates a sub progress monitor that will consume the given number of ticks from the receiver.
    `void` | `setBlocked​(IStatus reason)` |
    `void` | `setCanceled​(boolean b)` |
    `void` | `setTaskName​(java.lang.String name)` |
    `SubMonitor` | `setWorkRemaining​(int workRemaining)` | Sets the work remaining for this SubMonitor instance.
    `void` | `skipped()` | Same as `skipped(1)`.
    `void` | `skipped​(int ticks)` | Same as `setWorkRemaining(totalParent - usedForParent)`.
    `void` | `subTask​(java.lang.String name)` |
    `void` | `worked()` | Same as `worked(1)`.
    `void` | `worked​(int work)` |

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

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

    - ### Methods inherited from interface org.eclipse.core.runtime.IProgressMonitor

      `slice`

- - ### Field Detail

    - #### DEFAULT_WORK

          public static final int DEFAULT_WORK

      See Also:
        Constant Field Values

    - #### SUPPRESS_SUBTASK

          public static final int SUPPRESS_SUBTASK

      May be passed as a flag to newChild. Indicates that the calls to subTask on the child should be ignored. Without this flag, calling subTask on the child will result in a call to subTask on its parent.
      See Also:
        Constant Field Values

    - #### SUPPRESS_BEGINTASK

          public static final int SUPPRESS_BEGINTASK

      May be passed as a flag to newChild. Indicates that strings passed into beginTask should be ignored. If this flag is specified, then the progress monitor instance will accept null as the first argument to beginTask. Without this flag, any string passed to beginTask will result in a call to setTaskName on the parent.
      See Also:
        Constant Field Values

    - #### SUPPRESS_SETTASKNAME

          public static final int SUPPRESS_SETTASKNAME

      May be passed as a flag to newChild. Indicates that strings passed into setTaskName should be ignored. If this string is omitted, then a call to setTaskName on the child will result in a call to setTaskName on the parent.
      See Also:
        Constant Field Values

    - #### SUPPRESS_ALL_LABELS

          public static final int SUPPRESS_ALL_LABELS

      May be passed as a flag to newChild. Indicates that strings passed to setTaskName, subTask, and beginTask should all be ignored.
      See Also:
        Constant Field Values

    - #### SUPPRESS_NONE

          public static final int SUPPRESS_NONE

      May be passed as a flag to newChild. Indicates that strings passed to setTaskName, subTask, and beginTask should all be propagated to the parent.
      See Also:
        Constant Field Values

  - ### Method Detail

    - #### convert

          public static SubMonitor convert​(IProgressMonitor monitor)

      Converts an unknown (possibly null) IProgressMonitor into a SubMonitor. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.

      This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.

      Parameters:
        `monitor` - monitor to convert to a SubMonitor instance or null. Treats null as a new instance of `NullProgressMonitor`.
      Returns:
        a SubMonitor instance that adapts the argument

    - #### convert

          public static SubMonitor convert​(IProgressMonitor monitor,
                                           int work)

      Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.

      This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.

      Parameters:
        `monitor` - monitor to convert to a SubMonitor instance or null. Treats null as a new instance of `NullProgressMonitor`.
        `work` - number of ticks that will be available in the resulting monitor
      Returns:
        a SubMonitor instance that adapts the argument

    - #### convert

          public static SubMonitor convert​(IProgressMonitor monitor,
                                           java.lang.String taskName,
                                           int work)

      Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.

      This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.

      Parameters:
        `monitor` - to convert into a SubMonitor instance or null. If given a null argument, the resulting SubMonitor will not report its progress anywhere.
        `taskName` - user readable name to pass to monitor.beginTask. Never null.
        `work` - initial number of ticks to allocate for children of the SubMonitor
      Returns:
        a new SubMonitor instance that is a child of the given monitor

    - #### convert

          public static SubMonitor convert​(IProgressMonitor monitor,
                                           SubMonitor.ProbingMode probingMode)

      Converts an unknown (possibly null) IProgressMonitor into a SubMonitor. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.

      This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.

      Parameters:
        `monitor` - monitor to convert to a SubMonitor instance or null. Treats null as a new instance of `NullProgressMonitor`.
      Returns:
        a SubMonitor instance that adapts the argument

    - #### convert

          public static SubMonitor convert​(IProgressMonitor monitor,
                                           int work,
                                           SubMonitor.ProbingMode probingMode)

      Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.

      This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.

      Parameters:
        `monitor` - monitor to convert to a SubMonitor instance or null. Treats null as a new instance of `NullProgressMonitor`.
        `work` - number of ticks that will be available in the resulting monitor
      Returns:
        a SubMonitor instance that adapts the argument

    - #### convert

          public static SubMonitor convert​(IProgressMonitor monitor,
                                           java.lang.String taskName,
                                           int work,
                                           SubMonitor.ProbingMode probingMode)

      Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.

      This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.

      Parameters:
        `monitor` - to convert into a SubMonitor instance or null. If given a null argument, the resulting SubMonitor will not report its progress anywhere.
        `taskName` - user readable name to pass to monitor.beginTask. Never null.
        `work` - initial number of ticks to allocate for children of the SubMonitor
      Returns:
        a new SubMonitor instance that is a child of the given monitor

    - #### detectCancelation

          public final SubMonitor detectCancelation()

    - #### detectCancelation

          public final SubMonitor detectCancelation​(boolean on)

    - #### setWorkRemaining

          public final SubMonitor setWorkRemaining​(int workRemaining)

      Sets the work remaining for this SubMonitor instance. This is the total number of ticks that may be reported by all subsequent calls to worked(int), newChild(int), etc. This may be called many times for the same SubMonitor instance. When this method is called, the remaining space on the progress monitor is redistributed into the given number of ticks.

      It doesn't matter how much progress has already been reported with this SubMonitor instance. If you call setWorkRemaining(100), you will be able to report 100 more ticks of work before the progress meter reaches 100%.

      Parameters:
        `workRemaining` - total number of remaining ticks
      Returns:
        the receiver

    - #### isCanceled

          public final boolean isCanceled()

      Specified by:
        `isCanceled` in interface `IProgressMonitor`

    - #### setTaskName

          public final void setTaskName​(java.lang.String name)

      Specified by:
        `setTaskName` in interface `IProgressMonitor`

    - #### beginTask

          public final void beginTask​(java.lang.String name,
                                      int totalWork)

      Starts a new main task. The string argument is ignored if and only if the SUPPRESS_BEGINTASK flag has been set on this SubMonitor instance.

      This method is equivalent calling setWorkRemaining(...) on the receiver. Unless the SUPPRESS_BEGINTASK flag is set, this will also be equivalent to calling setTaskName(...) on the parent.

      Specified by:
        `beginTask` in interface `IProgressMonitor`
      Parameters:
        `name` - new main task name
        `totalWork` - number of ticks to allocate
      See Also:
        `IProgressMonitor.beginTask(java.lang.String, int)`

    - #### done

          public void done()

      Specified by:
        `done` in interface `IProgressMonitor`

    - #### internalWorked

          public final void internalWorked​(double work)

      Specified by:
        `internalWorked` in interface `IProgressMonitor`

    - #### subTask

          public final void subTask​(java.lang.String name)

      Specified by:
        `subTask` in interface `IProgressMonitor`

    - #### worked

          public final void worked()

      Same as `worked(1)`.

    - #### worked

          public void worked​(int work)

      Specified by:
        `worked` in interface `IProgressMonitor`

    - #### skipped

          public final void skipped​(int ticks)

      Same as `setWorkRemaining(totalParent - usedForParent)`.

    - #### skipped

          public final void skipped()

      Same as `skipped(1)`.

    - #### setCanceled

          public final void setCanceled​(boolean b)

      Specified by:
        `setCanceled` in interface `IProgressMonitor`

    - #### newChild

          public final SubMonitor newChild()

      Same as `newChild(1)`.

    - #### newChild

          public final SubMonitor newChild​(int totalWork)

      Creates a sub progress monitor that will consume the given number of ticks from the receiver. It is not necessary to call `beginTask` or `done` on the result. However, the resulting progress monitor will not report any work after the first call to done() or before ticks are allocated. Ticks may be allocated by calling beginTask or setWorkRemaining.

      Each SubMonitor only has one active child at a time. Each time newChild() is called, the result becomes the new active child and any unused progress from the previously-active child is consumed.

      This is property makes it unnecessary to call done() on a SubMonitor instance, since child monitors are automatically cleaned up the next time the parent is touched.

                ////////////////////////////////////////////////////////////////////////////
                // Example 1: Typical usage of newChild
                void myMethod(IProgressMonitor parent) {
                    SubMonitor progress = SubMonitor.convert(parent, 100);
                    doSomething(progress.newChild(50));
                    doSomethingElse(progress.newChild(50));
                }

                ////////////////////////////////////////////////////////////////////////////
                // Example 2: Demonstrates the function of active children. Creating children
                // is sufficient to smoothly report progress, even if worked(...) and done()
                // are never called.
                void myMethod(IProgressMonitor parent) {
                    SubMonitor progress = SubMonitor.convert(parent, 100);

                    for (int i = 0; i < 100; i++) {
                        // Creating the next child monitor will clean up the previous one,
                        // causing progress to be reported smoothly even if we don't do anything
                        // with the monitors we create
                      progress.newChild(1);
                    }
                }

                ////////////////////////////////////////////////////////////////////////////
                // Example 3: Demonstrates a common anti-pattern
                void wrongMethod(IProgressMonitor parent) {
                    SubMonitor progress = SubMonitor.convert(parent, 100);

                    // WRONG WAY: Won't have the intended effect, as only one of these progress
                    // monitors may be active at a time and the other will report no progress.
                    callMethod(progress.newChild(50), computeValue(progress.newChild(50)));
                }

                void rightMethod(IProgressMonitor parent) {
                    SubMonitor progress = SubMonitor.convert(parent, 100);

                    // RIGHT WAY: Break up method calls so that only one SubMonitor is in use at a time.
                    Object someValue = computeValue(progress.newChild(50));
                    callMethod(progress.newChild(50), someValue);
                }

      Parameters:
        `totalWork` - number of ticks to consume from the receiver
      Returns:
        new sub progress monitor that may be used in place of a new SubMonitor

    - #### newChild

          public final SubMonitor newChild​(int totalWork,
                                           int suppressFlags)

      Creates a sub progress monitor that will consume the given number of ticks from the receiver. It is not necessary to call `beginTask` or `done` on the result. However, the resulting progress monitor will not report any work after the first call to done() or before ticks are allocated. Ticks may be allocated by calling beginTask or setWorkRemaining.

      Each SubMonitor only has one active child at a time. Each time newChild() is called, the result becomes the new active child and any unused progress from the previously-active child is consumed.

      This is property makes it unnecessary to call done() on a SubMonitor instance, since child monitors are automatically cleaned up the next time the parent is touched.

                ////////////////////////////////////////////////////////////////////////////
                // Example 1: Typical usage of newChild
                void myMethod(IProgressMonitor parent) {
                    SubMonitor progress = SubMonitor.convert(parent, 100);
                    doSomething(progress.newChild(50));
                    doSomethingElse(progress.newChild(50));
                }

                ////////////////////////////////////////////////////////////////////////////
                // Example 2: Demonstrates the function of active children. Creating children
                // is sufficient to smoothly report progress, even if worked(...) and done()
                // are never called.
                void myMethod(IProgressMonitor parent) {
                    SubMonitor progress = SubMonitor.convert(parent, 100);

                    for (int i = 0; i < 100; i++) {
                        // Creating the next child monitor will clean up the previous one,
                        // causing progress to be reported smoothly even if we don't do anything
                        // with the monitors we create
                      progress.newChild(1);
                    }
                }

                ////////////////////////////////////////////////////////////////////////////
                // Example 3: Demonstrates a common anti-pattern
                void wrongMethod(IProgressMonitor parent) {
                    SubMonitor progress = SubMonitor.convert(parent, 100);

                    // WRONG WAY: Won't have the intended effect, as only one of these progress
                    // monitors may be active at a time and the other will report no progress.
                    callMethod(progress.newChild(50), computeValue(progress.newChild(50)));
                }

                void rightMethod(IProgressMonitor parent) {
                    SubMonitor progress = SubMonitor.convert(parent, 100);

                    // RIGHT WAY: Break up method calls so that only one SubMonitor is in use at a time.
                    Object someValue = computeValue(progress.newChild(50));
                    callMethod(progress.newChild(50), someValue);
                }

      Parameters:
        `totalWork` - number of ticks to consume from the receiver
      Returns:
        new sub progress monitor that may be used in place of a new SubMonitor

    - #### childDone

          public void childDone()

    - #### clearBlocked

          public final void clearBlocked()

      Specified by:
        `clearBlocked` in interface `IProgressMonitor`

    - #### setBlocked

          public final void setBlocked​(IStatus reason)

      Specified by:
        `setBlocked` in interface `IProgressMonitor`

    - #### eq

          protected static boolean eq​(java.lang.Object o1,
                                      java.lang.Object o2)