# Finalizable.java

    /*
    ** Module   : Finalizable.java
    ** Abstract : The interface for objects whose changes must be externally
    **            finalized at exit from the given block in which they are defined
    **
    ** Copyright (c) 2005-2020, Golden Code Development Corporation.
    **
    ** -#- -I- --Date-- --JPRM-- -----------------------------Description-----------------------------
    ** 001 GES 20050811   @22109 Created initial version, providing an interface for objects whose
    **                           changes must be externally finalized at exit from the given block
    **                           in which they are defined.
    ** 002 ECF 20051104   @23235 Added iterate method. Provides notice after the current block has
    **                           been processed, just before another iteration pass is attempted.
    ** 003 GES 20060517   @26190 Added retry method. Provides notice just before a retry of the
    **                           current block will occur. This allows resources to be cleaned up or
    **                           reset as needed.
    ** 004 GES 20060804   @28427 Major javadoc improvements.
    ** 005 CA  20131013          Added deleted() API, which will be called when the instantiating
    **                           procedure where this finalizable was registered gets deleted.
    ** 006 OM  20160223          Added initFailure() API, which will be called in the event that the
    **                           the instantiating procedure fails.
    ** 007 CA  20190812          Added weight(), to allow to sort the finalizable instances, before
    **                           processing them.
    ** 008 GES 20200316          Added entry() which is called once (and only ever once) after the
    **                           one-time block initialization and before the block body executes
    **                           for the first time.  This is the equivalent to iterate() except
    **                           it occurs at the top of the first iteration (or the first block
    **                           execution) instead of only being called on the second and subsequent
    **                           iterations.
    */

    /*
    ** This program is free software: you can redistribute it and/or modify
    ** it under the terms of the GNU Affero General Public License as
    ** published by the Free Software Foundation, either version 3 of the
    ** License, or (at your option) any later version.
    **
    ** This program is distributed in the hope that it will be useful,
    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ** GNU Affero General Public License for more details.
    **
    ** You may find a copy of the GNU Affero GPL version 3 at the following
    ** location: https://www.gnu.org/licenses/agpl-3.0.en.html
    **
    ** Additional terms under GNU Affero GPL version 3 section 7:
    **
    **   Under Section 7 of the GNU Affero GPL version 3, the following additional
    **   terms apply to the works covered under the License.  These additional terms
    **   are non-permissive additional terms allowed under Section 7 of the GNU
    **   Affero GPL version 3 and may not be removed by you.
    **
    **   0. Attribution Requirement.
    **
    **     You must preserve all legal notices or author attributions in the covered
    **     work or Appropriate Legal Notices displayed by works containing the covered
    **     work.  You may not remove from the covered work any author or developer
    **     credit already included within the covered work.
    **
    **   1. No License To Use Trademarks.
    **
    **     This license does not grant any license or rights to use the trademarks
    **     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
    **     of Golden Code Development Corporation. You are not authorized to use the
    **     name Golden Code, FWD, or the names of any author or contributor, for
    **     publicity purposes without written authorization.
    **
    **   2. No Misrepresentation of Affiliation.
    **
    **     You may not represent yourself as Golden Code Development Corporation or FWD.
    **
    **     You may not represent yourself for publicity purposes as associated with
    **     Golden Code Development Corporation, FWD, or any author or contributor to
    **     the covered work, without written authorization.
    **
    **   3. No Misrepresentation of Source or Origin.
    **
    **     You may not represent the covered work as solely your work.  All modified
    **     versions of the covered work must be marked in a reasonable way to make it
    **     clear that the modified work is not originating from Golden Code Development
    **     Corporation or FWD.  All modified versions must contain the notices of
    **     attribution required in this license.
    */

    package com.goldencode.p2j.util;

    import com.goldencode.p2j.security.*;

    /**
     * An interface for objects whose changes can be externally finalized at exit
     * from the given block in which they are defined.  This is guaranteed to be
     * called no matter how the flow of control exits the block (exception,
     * break, return or via the flow of control passing through the natural end
     * of the block).  Also provides a notification before the first block execution
     * after each iteration of the block and before a block retry.
     */
    public interface Finalizable
    {
       /**
        * Provides a notification that the scope in which the object is
        * registered is ending and the object's reference may or may not be lost after
        * this method is called.  This provides a natural and standard mechanism
        * to cleanup any resources that may need to be closed explicitly such
        * as operating system files or sockets.
        * <p>
        * This processing is guaranteed to be called after all processing of the
        * block body has occurred, no matter whether the exit from the block is
        * occurring due to natural flow control (the end of the block was
        * reached), a <code>continue</code>, a <code>return</code>, an exception
        * was thrown or an error raised.
        * <p>
        * If this is called, one can be sure that {@link #iterate} and
        * {@link #retry} have not been called without the loop body executing
        * afterwards (but before this notification occurred).
        */
       public void finished();

       /**
        * Provides a notification that procedure this object was registered failed initialization and
        * allows eventual cleanup to be performed. In this case the {@code finished()} will not be
        * called because the scope of the procedure haven't started yet.
        * <p>
        * Usually the implementation will call {@code finished()} if the registration occurs before
        * the procedure scope was started and some preparations that need rollback were made.
        * Otherwise this method should be kept empty.
        */
       public default void initFailure()
       {
       }

       /**
        * Provides a notification that the external program in which the object is registered is
        * being deleted and the object's reference may be lost after this method is called.
        */
       public void deleted();

       /**
        * Notification which is called once (and only ever once) after the one-time block
        * initialization (the {@code Block.init()} and before the block body {@code Block.body()}
        * executes for the first time.  This is the counterpart to {@code iterate()} except it occurs
        * at the top of the first iteration (or the first block execution for non-loops) instead of
        * only being called on the second and subsequent iterations.  {@code iterate()} is not
        * called for the first iteration of a loop (and is never called for non-loops).
        */
       public default void entry()
       {
       }

       /**
        * Provides a notification that the block whose scope in which the object is registered is
        * about to iterate and attempt another pass.  This provides an opportunity to preserve state
        * from the previous pass and make preparations for the coming pass.
        * <p>
        * This hook is called at the top of the loop, just after the loop test has been passed.  If
        * the loop test fails, then this will not be called. This code will be called inside the
        * block itself, as the first thing that is done.
        * <p>
        * Note that this is only called on the second and subsequent iterations of the block, no
        * matter how the iteration occurred (via natural control flow through the bottom of an
        * iterating block OR via a Java {@code continue} statement that caused a jump to the top of
        * the loop).
        * <p>
        * If the block is not a loop (an iterating block), this method will NOT be executed.
        * <p>
        * If this is called, one can be sure that a retry is NOT in process and that at least 1
        * statement in the block body will be executed before a {@link #finished} notification will
        * occur.
        * <p>
        * On the first iteration (or the non-loop block execution) the {@code entry()} will be
        * called instead of {@code iterate()}. {@code iterate()} is never called in those cases.
        */
       public void iterate();

       /**
        * Provides a notification that the block whose scope in which the object
        * is registered is about to retry the same iteration (all loop control
        * data is unchanged).  This provides an opportunity to clear or reset
        * state from the previous pass.
        * <p>
        * This hook is called at the bottom of the block, before iterating or
        * exiting IF AND ONLY IF a retry is about to occur.  On a retry, the loop
        * condition of any iterating block will not be subsequently executed, nor
        * will there be any backup/snapshot of undoable variables.
        * <p>
        * If this is called, one can be sure that neither an {@link #iterate}
        * nor a {@link #finished} notification will occur before at least 1
        * statement in the block body is executed.
        * <p>
        * A retry can occur whether or not this is an iterating block (a loop).
        */
       public void retry();

       /**
        * Get the weight of this finalizable.  Instances will ordered by their
        * {@link WeightFactor weight}, before they are processed.
        *
        * @return   The weight of this finalizable.  By default, it returns
        *           {@link WeightFactor#LAST}.
        */
       public default WeightFactor weight()
       {
          return WeightFactor.LAST;
       }
    }