# DeferredProgramWrapper.java

    /*
    ** Module   : DeferredProgramWrapper.java
    ** Abstract : Implements the deferred program resource, for SINGLE-RUN or SINGLETON modes.
    **
    ** Copyright (c) 2019-2023, Golden Code Development Corporation.
    **
    ** -#- -I- --Date-- ---------------------------------Description----------------------------------
    ** 001 CA  20190628 Created initial version.
    ** 002 AIL 20200622 Made use of the new procedure delete signature.
    **                  Changed the behavior of multiple deletes when there is a server instance.
    ** 003 ME  20201203 Internal entries is unknown for 'proxy' procedures.
    ** 004 CA  20230110 Cache the helper for ProcedureManager, ObjectOps and others (as needed), to reduce
    **                  context-local lookup.
    */
    /*
    ** 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.util.ProcedureManager.SearchMode;

    /**
     * This program represents the instance used to assign to a handle, when a statement like
     * <code>RUN ... {SINGLETON|SINGLE-RUN} SET h</code> is executed.
     * <p>
     * This saves a {@link DeferredProgram} instance, with the details of the program to be ran, when
     * one if its internal-entries (or methods, for legacy classes) is accessed.
     */
    public class DeferredProgramWrapper
    extends ExternalProgramWrapper
    {
       /**
        * Create a new wrapper.
        *
        * @param    deferred
        *           The configuration to defer this invocation.
        */
       public DeferredProgramWrapper(DeferredProgram deferred)
       {
          super(deferred);
       }

       /**
        * Get the <code>persistent</code> attribute of this instance.
        *
        * @return   Always <code>false</code>.
        */
       public logical isPersistent()
       {
          return new logical(false);
       }

       /**
        * Get the <code>INTERNAL-ENTRIES</code> attribute of this instance.
        *
        * @return   Always empty string.
        */
       public character internalEntries()
       {
          return new character();
       }

       /**
        * Execute the <code>GET-SIGNATURE</code> method of this instance.
        *
        * @param    internalEntry
        *           The legacy name of the internal-entry for which the signature is needed.
        *
        * @return   Always empty string.
        */
       public character getSignature(character internalEntry)
       {
          return new character("");
       }

       /**
        * Get the <code>SUPER-PROCEDURES</code> attribute of this instance.
        *
        * @return   Always empty string.
        */
       public character superProcedures()
       {
          return new character("");
       }

       /**
        * Add the given handle as a super-procedure for the current handle.
        *
        * @param    h
        *           The handle to be added as a super-procedure.
        *
        * @return   Always <code>false</code>.
        */
       public logical addSuperProcedure(handle h)
       {
          return new logical(false);
       }

       /**
        * Add the given handle as a super-procedure for the current handle, using
        * the explicit {@link SearchMode mode}.
        *
        * @param    h
        *           The handle to be added as a super-procedure.
        * @param    mode
        *           The {@link SearchMode} to be set for the <code>h</code> handle.
        *
        * @return   Always <code>false</code>.
        */
       public logical addSuperProcedure(handle h, SearchMode mode)
       {
          return new logical(false);
       }

       /**
        * Add the given handle as a super-procedure for the current handle, using
        * the search-mode set as a string (one of the <code>SEARCH-TARGET</code>
        * or <code>SEARCH-SELF</code> string literals).
        *
        * @param    h
        *           The handle to be added as a super-procedure.
        * @param    mode
        *           The search-mode to be set for the <code>h</code> handle.
        *
        * @return   Always <code>false</code>.
        */
       public logical addSuperProcedure(handle h, int mode)
       {
          return new logical(false);
       }

       /**
        * Add the given handle as a super-procedure for the current handle, using
        * the search-mode set as a string (one of the <code>SEARCH-TARGET</code>
        * or <code>SEARCH-SELF</code> string literals).
        *
        * @param    h
        *           The handle to be added as a super-procedure.
        * @param    mode
        *           The search-mode to be set for the <code>h</code> handle.
        *
        * @return   Always <code>false</code>.
        */
       public logical addSuperProcedure(handle h, integer mode)
       {
          return new logical(false);
       }

       /**
        * Remove the given handle from this handle's list of super-procedures.
        *
        * @param    h
        *           The procedure handle to be removed.
        *
        * @return   Always <code>false</code>.
        */
       public logical removeSuperProcedure(handle h)
       {
          return new logical(false);
       }

       /**
        * Indicates if the procedure is a proxy procedure.
        *
        * @return   always <code>true</code>
        */
       public logical isProxy()
       {
          return new logical(true);
       }

       /**
        * Get the named events published by this procedure.
        *
        * @return    Always empty string.
        */
       @Override
       public character getPublishedEvents()
       {
          return new character("");
       }

       /**
        * Get the <code>NEXT-SIBLING</code> attribute of this instance.
        *
        * @return   Always an unknown value.
        */
       public handle getNextSibling()
       {
          return new handle();
       }

       /**
        * Get the <code>PREV-SIBLING</code> attribute of this instance.
        *
        * @return   Always an unknown value.
        */
       public handle getPrevSibling()
       {
          return new handle();
       }

       /**
        * Perform actual delete of this procedure, by calling {@link ProcedureManager#delete(Object, boolean)}.
        */
       public void delete()
       {
          if (pm.delete(this.get(), ((DeferredProgram) referent).getServer() == null))
          {
             // cleanup after it
             handle.removeResource(this);
          }
       }

       /**
        * A deferred program wrapper is eligible for multiple deletes only if there is no server instance.
        */
       @Override
       public boolean handleMultipleDeletes()
       {
          return ((DeferredProgram) referent).getServer() == null;
       }
    }