001    /*
002     * Copyright (c) 1998-2014 ChemAxon Ltd. All Rights Reserved.
003     *
004     * This software is the confidential and proprietary information of
005     * ChemAxon. You shall not disclose such Confidential Information
006     * and shall use it only in accordance with the terms of the agreements
007     * you entered into with ChemAxon.
008     *
009     */
010    
011    package com.chemaxon.calculations.common;
012    
013    import com.chemaxon.common.annotations.PublicAPI;
014    import com.google.common.annotations.Beta;
015    
016    /**
017     * Observer for reporting the progress of long running tasks.
018     *
019     * <p>The semantics of this observer is influenced by the progress reporting facility of the Eclipse Platform; for
020     * details see <code>org.eclipse.core.runtime.IProgressMonitor</code>, associated classes/interfaces and documentations:
021     * <ul>
022     *     <li><code>IProgressMonitor</code> API: <a href="http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcore%2Fruntime%2FIProgressMonitor.html">http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcore%2Fruntime%2FIProgressMonitor.html</a></li>
023     *     <li>Detailed description: <a href="http://www.eclipse.org/articles/Article-Progress-Monitors/article.html">http://www.eclipse.org/articles/Article-Progress-Monitors/article.html</a></li>
024     * </ul>
025     * </p>
026     *
027     * <p>Design aspects of this progress observing facility:
028     * <ul>
029     *     <li>The execution observed is divided into work units.</li>
030     *     <li>The sum of the remaining work units needed to be processed up to the completion of the work can be known
031     *         exactly prior execution, can become known during process or remain unknown.</li>
032     *     <li>Some of the work units can be observed through a sub observer in a more detailed way. The total work units
033     *         done on the upper level represented by the completion of the sub task must be specified,</li>
034     *     <li>Work units/subtasks might be worked/completed asynchronously</li>
035     *     <li>ProgressObservers also used for cancellation reporting. Since it is a cross cutting concern it is exposed
036     *         as a separate but extended interface.</li>
037     *     <li>ProgressObserver starts in an indefinite state and can transit to definite when the amount of remaining work
038     *         became known. Transition back to indefinite state is not possible.</li>
039     *     <li>Please note that certain implementations might not provide strict API contract enforcement.</li>
040     * </ul></p>
041     *
042     * <p>Thread safety: an instance is not guaranteed to be thread safe.</p>
043     *
044     * <p>Please note that this interface is marked with @Beta annotation, so it can be subject of incompatible changes or
045     * removal in later releases.</p>
046     *
047     *
048     * @author Gabor Imre
049     */
050    //  TODO: include appropriate license
051    
052    @Beta
053    @PublicAPI
054    public interface ProgressObserver extends CancelObserver {
055    
056        /**
057         * Notifies that the remaining amount of work units to complete this task is known.
058         *
059         * <p>Call this when the represented total work to be done is known or became known. It is valid to call this
060         * method after work units already reported in indeterminate mode</p>
061         *
062         * @param totalWork                  The total amount of work represented by this task.
063         * @throws IllegalStateException     When this method already called
064         * @throws IllegalArgumentException  When <code>totalWork</code> is zero or negative
065         */
066        void switchToDeterminate(long totalWork);
067    
068        /**
069         * Notifies that a given number of work units has been completed.
070         *
071         * <p>Note that this amount represents an installment, as opposed to a cumulative amount of work done to date.</p>
072         *
073         * @param work                       Amount of work reported
074         *
075         * @throws IllegalStateException     When the total amount of work known
076         *                                   and already logged (or expected to be logged) amount exceeds it. Also when no
077         *                                   <code>done()</code> is already invoked or the observer is closed in other
078         *                                   implementation specific way.
079         *
080         * @throws IllegalArgumentException  When <code>work</code> is zero or negative
081         */
082        void worked(long work);
083    
084        /**
085         * Follow the processing of a specific amount of work units by a separate observer.
086         *
087         * <p>The given amount of work on the level of the current observer is considered completed upon
088         * {@link SubProgressObserver#done()} called on the returned subtask's observer.</p>
089         *
090         * <p>Cancel propagation is expected to be transparent.</p>
091         *
092         * <p>The strict contract regarding the state when {@link ProgressObserver#worked(long)} can be called is relaxed in
093         * the context of subtask observers: implicitly logging work on the upper level by calling
094         * {@link SubProgressObserver#done()} on the subtask level <b>after</b> the upper level is closed will no cause
095         * problem on either level.</p>
096         *
097         * @param name                       Name of the represented sub task (for example to display)
098         * @param work                       A non-negative number of work units considered to be completed upon finishing
099         *                                   the associated subtask.
100         * @return                           An unitialized observer to be used by a subtask. The returned observer will
101         *                                   reflect the same cancelling behavior as the current one.
102         *
103         * @throws IllegalStateException     When the total amount of work known
104         *                                   ({@link ProgressObserver#switchToDeterminate(long)}
105         *                                   and already logged (or expected to be logged) amount exceeds it.
106         *
107         * @throws IllegalArgumentException  When <code>work</code> is zero or negative
108         */
109        SubProgressObserver subTask(String name, long work);
110    
111    
112    }