ExternalProgramWrapper.java
/*
** Module : ExternalProgramWrapper.java
** Abstract : container that implements persistent-procedure related APIs.
**
** Copyright (c) 2012-2025, Golden Code Development Corporation.
**
** -#- -I- --Date-- ---------------------------------------Description---------------------------------------
** 002 CA 20121220 Created initial version.
** 003 CS 20130211 Added conversion support for app server.
** 004 CA 20130221 getType getter for TYPE attribute was renamed to getResourceType.
** Added ADM-DATA and UNIQUE-ID support.
** 005 CS 20130221 Added conversion support for CURRENT-WINDOW attribute.
** 006 CA 20130223 Added stubs for SET-CALLBACK-PROCEDURE method.
** 007 OM 20130304 Refactored isValid and isUnknown of WrappedResource to valid and unknown.
** 008 CA 20130529 Added implementation for REMOTE, SERVER-HANDLE and PROXY attributes.
** Implemented the resource delete here.
** 009 CA 20130813 Added support for the ASYNC-REQUEST-COUNT attribute.
** 010 CA 20130919 Resource cleanup must be done after it was deleted.
** 011 CA 20130925 Added support for PUBLISHED-EVENTS attribute.
** 012 CA 20130927 Resource type is determined from LegacyResource constant; the annotation is
** ignored, as it doesn't extend HandleResource.
** 013 EVL 20131014 Adding annotation for legacy attributes to be ignored for the class.
** 014 SVL 20131203 Changes caused by renaming of Nameable.get/setName to Nameable.name.
** 015 CA 20131013 Added support for INSTANTIATING-PROCEDURE attribute.
** 016 CA 20131208 Emit SEARCH-TARGET and SEARCH-SELF literals as integer. Do note delete the
** procedure if is active on the call stack.
** 017 HC 20131222 Implemented ADM-DATA and UNIQUE-ID attribute.
** INSTANTIATING-PROCEDURE is now managed by ProcedureManager.
** 018 CA 20140107 Implemented setCallbackProcedure for procedures associated with an external
** program.
** 019 VIG 20140108 Implemented CURRENT-WINDOW attribute.
** 020 CA 20140218 NAME and FILE-NAME return the program name as used at the RUN call (the
** "relative name"). Internally, the absolute program name must be used.
** 021 SVL 20170126 Added no-op setters for FILE-NAME.
** 022 CA 20181112 Implemented the PROCEDURE:TRANSACTION attribute.
** 023 CA 20190628 Added SINGLE-RUN and SINGLETON support.
** 024 VVT 20200131 Missing @Override annotations added. Code cleanup.
** 025 AIL 20200518 Added support for MultiDeletable.
** AIL 20200622 Made use of the new procedure delete signature. Fixed the multidelete.
** Use the StaleProcedureHelper instead of a singleton.
** OM 20201120 Added missing CALLBACK management methods.
** OM 20201203 Fixed handling of READ/ONLY attributes.
** CA 20211214 For State-free appservers, the agents can be bound to remote persistent procedures; this
** binding must be made using the agent's ID, as a client can invoke multiple remote
** persistent procedures, and using the procedure's ID for this binding can lead to
** collisions, as the pair (connection ID, procedure ID) is not guaranteed to be unique for
** a connection.
** VVT 20221003 CommonHandle.getResourceType() method renamed to resourceType() to prevent conflicts
** with namesakes in DMO. See #6694.
** CA 20230110 Cache the helper for ProcedureManager, ObjectOps and others (as needed), to reduce
** context-local lookup.
** 026 CA 20230712 For cases when this is instantiated from deserialization over the network, do not resolve
** the ProcedureHelper if there is no security context.
** 027 GBB 20230825 SecurityManager context methods calls updated.
** 028 CA 20240918 Removed default methods from interfaces and moved them as concrete implementations, as
** default methods cause the Java metaspace to spike one order of magnitude.
** 029 CA 20250321 Added 'setCallback' overloads.
*/
/*
** 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.SecurityManager;
import com.goldencode.p2j.ui.*;
import com.goldencode.p2j.util.ProcedureManager.SearchMode;
/**
* This container adds support for all persistent-procedure related attributes
* and methods, such as:
* <ul>
* <li>INTERNAL-ENTRIES</li>
* <li>NAME</li>
* <li>FILE-NAME</li>
* <li>PERSISTENT</li>
* <li>TYPE</li>
* <li>NEXT-SIBLING</li>
* <li>PREV-SIBLING</li>
* <li>PRIVATE-DATA</li>
* <li>GET-SIGNATURE</li>
* <li>ADD-SUPER-PROCEDURE</li>
* <li>REMOVE-SUPER-PROCEDURE</li>
* <li>SUPER-PROCEDURES</li>
* <li>SERVER</li>
* <li>SINGLE-RUN</li>
* <li>SINGLETON</li>
* <li>ASYNC-REQUEST-COUNT</li>
* <li>INSTANTIATING-PROCEDURE</li>
* <li>CURRENT-WINDOW</li>
* </ul>
*/
public class ExternalProgramWrapper
extends TransparentWrapper
implements PersistentProcedure,
MultiDeletable,
DeferredDeletable
{
/** Helper to use the ProcedureManager without any context local lookups. */
protected final ProcedureManager.ProcedureHelper pm;
/**
* Constructs a new wrapper for the given external procedure instance.
*
* @param referent
* The external procedure instance.
*/
public ExternalProgramWrapper(Object referent)
{
super(referent);
pm = SecurityManager.getInstance().contextSm.hasContext() ?
ProcedureManager.getProcedureHelper() :
null;
}
/**
* Constructs a new wrapper for the given external procedure instance.
*
* @param referent
* The external procedure instance.
*/
public ExternalProgramWrapper(ProcedureManager.ProcedureHelper pm, Object referent)
{
super(referent);
this.pm = pm;
}
/**
* Determine if this instance is valid. This means that its
* {@link TransparentWrapper#referent} field must be set and valid. More,
* this must be a known procedure instance, registered with
* {@link ProcedureManager}.
*
* @return <code>true</code> if this instance is valid,
* <code>false</code> otherways.
*/
@Override
public boolean valid()
{
if (!super.valid())
{
return false;
}
return pm.hasReferent(referent);
}
/**
* API needed to implement read-only attribute assignment (a 4GL "feature").
*
* @param attribute
* The attribute's name.
*/
@Override
@Deprecated
public void readOnlyError(String attribute)
{
handle.readOnlyError(new handle(this), attribute, handle.UNKNOWN_ARGUMENT);
}
/**
* Shows a specific error, as this read-only {@code attribute} was used on the right-side of an assignment.
* If the {@code expr} is evaluated to {@code ?} (unknown value) and this attribute does not support it,
* a specific error is raised.
*
* @param attribute
* The read-only attribute.
* @param expr
* The expression whose value was attempted to be assigned to READ-ONLY attribute.
*/
public void readOnlyError(String attribute, Object expr)
{
handle.readOnlyError(new handle(this), attribute, expr);
}
/**
* Get the <code>INTERNAL-ENTRIES</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @return See above.
*/
@Override
public character internalEntries()
{
String pname = ProcedureManager.getAbsoluteName(referent);
boolean prv = this.referent == pm.thisProcedure().get();
return new character(SourceNameMapper.getInternalEntries(pname, prv));
}
/**
* Get the <code>NAME</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @return See above.
*/
@Override
public character name()
{
return getFileName();
}
/**
* Calls {@link handle#readOnlyError}, as this attribute is read-only for procedure handles.
*
* @param name
* Not used.
*/
@Override
@LegacyAttribute(name = "NAME", setter = true, ignore = true)
public void name(String name)
{
handle.readOnlyError(new handle(this), "name");
}
/**
* Calls {@link handle#readOnlyError}, as this attribute is read-only for procedure handles.
*
* @param name
* Not used.
*/
@Override
@LegacyAttribute(name = "NAME", setter = true, ignore = true)
public void name(character name)
{
name((String) null);
}
/**
* Get the <code>FILE-NAME</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @return See above.
*/
@Override
public character getFileName()
{
return new character(pm.getRelativeName(referent));
}
/**
* Get the <code>persistent</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @return See above.
*/
@Override
public logical isPersistent()
{
return pm.isPersistent(referent);
}
/**
* Get the <code>single-run</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @return See above.
*/
@Override
public logical isSingleRun()
{
return new logical(pm.isSingleRun(referent));
}
/**
* Get the <code>single-run</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @return See above.
*/
@Override
public logical isSingleton()
{
return new logical(pm.isSingleton(referent));
}
/**
* Get the <code>TYPE</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @return Always returns <code>"PROCEDURE"</code>.
*/
@Override
public character resourceType()
{
return new character(LegacyResource.PROCEDURE);
}
/**
* Get the <code>NEXT-SIBLING</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @return See above.
*/
@Override
public handle getNextSibling()
{
return pm.getNextSibling(referent);
}
/**
* Get the <code>PREV-SIBLING</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @return See above.
*/
@Override
public handle getPrevSibling()
{
return pm.getPrevSibling(referent);
}
/**
* Get the <code>PRIVATE-DATA</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @return See above.
*/
@Override
public character getPrivateData()
{
return pm.getPrivateData(referent);
}
/**
* Set the <code>PRIVATE-DATA</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @param data
* The new private-data value.
*/
@Override
public void setPrivateData(character data)
{
pm.setPrivateData(referent, data);
}
/**
* Set the <code>PRIVATE-DATA</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @param data
* The new private-data value.
*/
@Override
public void setPrivateData(String data)
{
setPrivateData(new character(data));
}
/**
* Execute the <code>GET-SIGNATURE</code> method of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @param internalEntry
* The legacy name of the internal-entry for which the signature
* is needed.
*
* @return The internal entry's signature.
*/
@Override
public character getSignature(String internalEntry)
{
return getSignature(new character(internalEntry));
}
/**
* Execute the <code>GET-SIGNATURE</code> method of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @param internalEntry
* The legacy name of the internal-entry for which the signature
* is needed.
*
* @return The internal entry's signature.
*/
@Override
public character getSignature(character internalEntry)
{
String ieName = internalEntry.toStringMessage();
String pname = ProcedureManager.getAbsoluteName(referent);
if ("".equals(ieName))
{
return new character(SourceNameMapper.getSignature(pname, ""));
}
// is safe to call both, because: if there are both func and proc with
// the same name, then the signature is for the func, not the proc
// (thus if the func is private, then is not seen).
// else, if no func with this name, proc is cheched
if (SourceNameMapper.isPrivate(pname, ieName, true) ||
SourceNameMapper.isPrivate(pname, ieName, false))
{
// am I calling this from THIS-PROCEDURE? if yes, then I have access
handle thisp = pm.thisProcedure();
String thisName = ProcedureManager.getAbsoluteName(thisp.get());
if (!CompareOps.equals(new character(pname), new character(thisName)))
{
// return blank
return new character("");
}
}
return new character(SourceNameMapper.getSignature(pname, ieName));
}
/**
* Get the <code>SUPER-PROCEDURES</code> attribute of this
* {@link TransparentWrapper#referent external procedure instance.}
*
* @return See above.
*/
@Override
public character superProcedures()
{
return pm.superProcedures(referent);
}
/**
* Add the given handle as a super-procedure for the current handle.
*
* @param h
* The handle to be added as a super-procedure.
*
* @return <code>true</code> if <code>h</code> is a valid procedure
* handle.
*/
@Override
public logical addSuperProcedure(handle h)
{
return pm.addSuperProcedure(referent, h);
}
/**
* 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 <code>true</code> if <code>h</code> is a valid procedure
* handle.
*/
@Override
public logical addSuperProcedure(handle h, SearchMode mode)
{
return pm.addSuperProcedure(referent, h, mode);
}
/**
* 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 <code>true</code> if <code>h</code> is a valid procedure
* handle.
*/
@Override
public logical addSuperProcedure(handle h, int mode)
{
return pm.addSuperProcedure(referent, h, mode);
}
/**
* 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 <code>true</code> if <code>h</code> is a valid procedure
* handle.
*/
@Override
public logical addSuperProcedure(handle h, integer mode)
{
if (mode.isUnknown())
{
return pm.addSuperProcedure(referent, h, (SearchMode) null);
}
return pm.addSuperProcedure(referent, h, mode.intValue());
}
/**
* Remove the given handle from this handle's list of super-procedures.
*
* @param h
* The procedure handle to be removed.
*
* @return <code>true</code> if <code>h</code> is a valid procedure
* handle.
*/
@Override
public logical removeSuperProcedure(handle h)
{
return pm.removeSuperProcedure(referent, h);
}
/**
* Get CURRENT-WINDOW attribute for given procedure handle.
*
* @return Reference to current window widget.
*/
@Override
public handle currentWindow()
{
handle phandle = new handle(this);
// TODO: handle validation
return LogicalTerminal.currentWindow(phandle);
}
/**
* Set CURRENT-WINDOW attribute for this procedure handle.
*
* @param h
* A handle for the window.
*/
@Override
public void setCurrentWindow(handle h)
{
handle phandle = new handle(this);
LogicalTerminal.setProcCurrentWindow(phandle, h);
}
/**
* Set CURRENT-WINDOW attribute for this procedure handle.
*
* @param win
* Window reference.
*/
@Override
public void setCurrentWindow(WindowWidget win)
{
setCurrentWindow(win.asWidgetHandle());
}
/**
* Indicates if the procedure is ran as the remote top-level AppServer.
*
* @return <code>true</code> if the procedure is ran remote , <code>false</code> otherwise.
*/
@Override
public logical isRemote()
{
return new logical(SessionUtils._isRemote() &&
(pm.isTopLevel(get()) ||
AppServerManager.hasProcedure(get())));
}
/**
* Returns a handle to the app server in which the procedure is ran.
*
* @return Always unknown.
*/
@Override
public handle getServerHandle()
{
return new handle();
}
/**
* Indicates if the procedure is a proxy procedure.
*
* @return always <code>false</code>
*/
@Override
public logical isProxy()
{
return new logical(false);
}
/**
* Returns a handle to the current opened transaction.
*
* @return See above
*/
@Override
public handle getTransaction()
{
return new handle(TransactionImpl.get());
}
/**
* Get the value of the ADM-DATA attribute.
*
* @return See above.
*/
@Override
public character getADMData()
{
return pm.getADMData(referent);
}
/**
* Set the value of the ADM-DATA attribute.
*
* @param value
* The new value.
*/
@Override
public void setADMData(String value)
{
pm.setADMData(referent, value);
}
/**
* Set the value of the ADM-DATA attribute.
*
* @param value
* The new value.
*/
@Override
public void setADMData(character value)
{
pm.setADMData(referent, value.getValue());
}
/**
* Gets the the unique ID number associated to this object by the underlying system. Not the
* same as the handle value itself.
*
* @return The integer number of the children.
*/
@Override
public integer getUniqueID()
{
return pm.getUniqueID(referent);
}
/**
* Applies a callback procedure, which allows execution of a defined event without duplicating
* the event procedure definition.
*
* @param eventName
* The event whose callback will be called.
*
* @return {@code true} if operation is successful.
*/
@Override
public logical applyCallback(Text eventName)
{
return applyCallback(eventName.toJavaType());
}
/**
* Retrieves the name of the internal procedure associated with the ABL callback for the
* specified event.
*
* @param eventName
* The name of the event.
*
* @return the name of the internal procedure associated with specified event.
*/
@Override
public character getCallbackProcName(Text eventName)
{
return getCallbackProcName(eventName.toJavaType());
}
/**
* Retrieves the handle of the procedure that contains the internal procedure associated
* with the ABL callback for the specified event
*
* @param eventName
* The name of the event.
*
* @return a handle to the procedure that contains the callback procedure.
*/
@Override
public handle getCallbackProcContext(Text eventName)
{
return getCallbackProcContext(eventName.toJavaType());
}
/**
* Configures a callback. Creates an association between a method within a class instance or
* an internal procedure within a persistent procedure, with an ABL callback event.
*
* @param callbackName
* The name of a callback.
* @param routineName
* The name of a method or an internal procedure to be associated.
* @param context
* The context in which the callback will be executed.
*
* @return {@code true} if operation is successful and {@code false} if the parameters are
* invalid.
*/
@Override
public logical setCallback(Text callbackName, Text routineName, object<?> context)
{
return setCallback(callbackName.toJavaType(), routineName.toJavaType(), context);
}
/**
* Configures a callback. Creates an association between a method within a class instance or
* an internal procedure within a persistent procedure, with an ABL callback event.
*
* @param callbackName
* The name of a callback.
* @param routineName
* The name of a method or an internal procedure to be associated.
* @param context
* The context in which the callback will be executed.
*
* @return {@code true} if operation is successful and {@code false} if the parameters are
* invalid.
*/
@Override
public logical setCallback(String callbackName, String routineName, handle context)
{
return setCallbackProcedure(callbackName, routineName, context);
}
/**
* Configures a callback. Creates an association between a method within a class instance or
* an internal procedure within a persistent procedure, with an ABL callback event.
*
* @param callbackName
* The name of a callback.
* @param routineName
* The name of a method or an internal procedure to be associated.
* @param context
* The context in which the callback will be executed.
*
* @return {@code true} if operation is successful and {@code false} if the parameters are
* invalid.
*/
@Override
public logical setCallback(Text callbackName, Text routineName, handle context)
{
return setCallbackProcedure(callbackName.toJavaType(), routineName.toJavaType(), context);
}
/**
* Configures a callback. Creates an association between a method within a class instance or
* an internal procedure within a persistent procedure, with an ABL callback event.
*
* @param callbackName
* The name of a callback.
* @param routineName
* The name of a method or an internal procedure to be associated.
* @param context
* The context in which the callback will be executed.
*
* @return {@code true} if operation is successful and {@code false} if the parameters are
* invalid.
*/
@Override
public logical setCallback(String callbackName, Text routineName, handle context)
{
return setCallbackProcedure(callbackName, routineName.toJavaType(), context);
}
/**
* Configures a callback. Creates an association between a method within a class instance or
* an internal procedure within a persistent procedure, with an ABL callback event.
*
* @param callbackName
* The name of a callback.
* @param routineName
* The name of a method or an internal procedure to be associated.
*
* @return {@code true} if operation is successful and {@code false} if the parameters are
* invalid.
*/
@Override
public logical setCallback(String callbackName, String routineName)
{
return setCallback(callbackName, routineName, (object<?>) null);
}
/**
* Configures a callback. Creates an association between a method within a class instance or
* an internal procedure within a persistent procedure, with an ABL callback event.
*
* @param callbackName
* The name of a callback.
* @param routineName
* The name of a method or an internal procedure to be associated.
*
* @return {@code true} if operation is successful and {@code false} if the parameters are
* invalid.
*/
@Override
public logical setCallback(Text callbackName, Text routineName)
{
return setCallback(callbackName.toJavaType(), routineName.toJavaType(), (object<?>) null);
}
/**
* Configures a callback. Creates an association between a method within a class instance or
* an internal procedure within a persistent procedure, with an ABL callback event.
*
* @param callbackName
* The name of a callback.
* @param routineName
* The name of a method or an internal procedure to be associated.
*
* @return {@code true} if operation is successful and {@code false} if the parameters are
* invalid.
*/
@Override
public logical setCallback(Text callbackName, String routineName)
{
return setCallback(callbackName.toJavaType(), routineName);
}
/**
* Configures a callback. Creates an association between a method within a class instance or
* an internal procedure within a persistent procedure, with an ABL callback event.
*
* @param callbackName
* The name of a callback.
* @param routineName
* The name of a method or an internal procedure to be associated.
*
* @return {@code true} if operation is successful and {@code false} if the parameters are
* invalid.
*/
@Override
public logical setCallback(String callbackName, Text routineName)
{
return setCallback(callbackName, routineName.toJavaType());
}
/**
* Configures a callback. Creates an association between a method within a class instance or
* an internal procedure within a persistent procedure, with an ABL callback event.
*
* @param callbackName
* The name of a callback.
* @param routineName
* The name of a method or an internal procedure to be associated.
* @param context
* The context in which the callback will be executed.
*
* @return {@code true} if operation is successful and {@code false} if the parameters are
* invalid.
*/
@Override
public logical setCallback(String callbackName, Text routineName, object<?> context)
{
return setCallback(callbackName, routineName.toJavaType(), context);
}
/**
* Configures a callback. Creates an association between a method within a class instance or
* an internal procedure within a persistent procedure, with an ABL callback event.
*
* @param callbackName
* The name of a callback.
* @param routineName
* The name of a method or an internal procedure to be associated.
* @param context
* The context in which the callback will be executed.
*
* @return {@code true} if operation is successful and {@code false} if the parameters are
* invalid.
*/
@Override
public logical setCallback(Text callbackName, String routineName, object<?> context)
{
return setCallback(callbackName.toJavaType(), routineName, context);
}
/**
* Configures a callback. Creates an association between a method within a class instance or
* an internal procedure within a persistent procedure, with an ABL callback event.
*
* @param callbackName
* The name of a callback.
* @param routineName
* The name of a method or an internal procedure to be associated.
* @param context
* The context in which the callback will be executed.
*
* @return {@code true} if operation is successful and {@code false} if the parameters are
* invalid.
*/
@Override
public logical setCallback(Text callbackName, String routineName, handle context)
{
return setCallback(callbackName.toJavaType(), routineName, context);
}
/**
* Associate the internal procedure with the given web-services event.
* <p>
* This method returns false if the event name is not valid.
* <p>
* For external procedures, this always shows an error.
*
* @param event
* The event name, must evaluate to one of the "REQUEST-HEADER" or the "RESPONSE-HEADER" strings.
* @param proc
* The internal procedure to be executed for this event, which will be executed using the current
* THIS-PROCEDURE reference. To remove a callback mapping, set the this parameter to the empty
* string.
* @param context
* The context in which the callback will be executed.
*
* @return <code>true</code> if the event was registered.
*/
@Override
public logical setCallback(String event, String proc, object<?> context)
{
UnimplementedFeature.missing("SET-CALLBACK-PROCEDURE(String event, String proc, object<?> context)");
return new logical();
}
/**
* Associate the internal procedure with the given web-services event.
* <p>
* This method returns false if the event name is not valid.
* <p>
* For external procedures, this always shows an error.
*
* @param event
* The event name, must evaluate to one of the "REQUEST-HEADER" or the
* "RESPONSE-HEADER" strings.
* @param proc
* The internal procedure to be executed for this event, which will be executed using
* the current THIS-PROCEDURE reference. To remove a callback mapping, set the this
* parameter to the empty string.
*
* @return <code>true</code> if the event was registered.
*/
@Override
public logical setCallbackProcedure(String event, String proc)
{
return setCallbackProcedure(new character(event), new character(proc),
pm.thisProcedure());
}
/**
* Associate the internal procedure with the given web-services event.
* <p>
* This method returns false if the event name is not valid.
* <p>
* For external procedures, this always shows an error.
*
* @param event
* The event name, must evaluate to one of the "REQUEST-HEADER" or the
* "RESPONSE-HEADER" strings.
* @param proc
* The internal procedure to be executed for this event, which will be executed using
* the current THIS-PROCEDURE reference. To remove a callback mapping, set the this
* parameter to the empty string.
*
* @return <code>true</code> if the event was registered.
*/
@Override
public logical setCallbackProcedure(character event, String proc)
{
return setCallbackProcedure(event, new character(proc), pm.thisProcedure());
}
/**
* Associate the internal procedure with the given web-services event.
* <p>
* This method returns false if the event name is not valid.
* <p>
* For external procedures, this always shows an error.
*
* @param event
* The event name, must evaluate to one of the "REQUEST-HEADER" or the
* "RESPONSE-HEADER" strings.
* @param proc
* The internal procedure to be executed for this event, which will be executed using
* the current THIS-PROCEDURE reference. To remove a callback mapping, set the this
* parameter to the empty string.
*
* @return <code>true</code> if the event was registered.
*/
@Override
public logical setCallbackProcedure(String event, character proc)
{
return setCallbackProcedure(new character(event), proc, pm.thisProcedure());
}
/**
* Associate the internal procedure with the given web-services event.
* <p>
* This method returns false if the event name is not valid.
* <p>
* For external procedures, this always shows an error.
*
* @param event
* The event name, must evaluate to one of the "REQUEST-HEADER" or the
* "RESPONSE-HEADER" strings.
* @param proc
* The internal procedure to be executed for this event, which will be executed using
* the current THIS-PROCEDURE reference. To remove a callback mapping, set the this
* parameter to the empty string.
*
* @return <code>true</code> if the event was registered.
*/
@Override
public logical setCallbackProcedure(character event, character proc)
{
return setCallbackProcedure(event, proc, pm.thisProcedure());
}
/**
* Associate the internal procedure with the given web-services event.
* <p>
* This method returns false if the event name is not valid or if the procedure's context is
* not a valid handle.
* <p>
* For external procedures, this always shows an error.
*
* @param event
* The event name, must evaluate to one of the "REQUEST-HEADER" or the
* "RESPONSE-HEADER" strings.
* @param proc
* The internal procedure to be executed for this event. To remove a callback
* mapping, set the this parameter to the empty string.
* @param context
* The procedure handle where the internal procedure will be searched and executed.
*
* @return <code>true</code> if the event was registered.
*/
@Override
public logical setCallbackProcedure(String event, String proc, handle context)
{
return setCallbackProcedure(new character(event), new character(proc), context);
}
/**
* Associate the internal procedure with the given web-services event.
* <p>
* This method returns false if the event name is not valid or if the procedure's context is
* not a valid handle.
* <p>
* For external procedures, this always shows an error.
*
* @param event
* The event name, must evaluate to one of the "REQUEST-HEADER" or the
* "RESPONSE-HEADER" strings.
* @param proc
* The internal procedure to be executed for this event. To remove a callback
* mapping, set the this parameter to the empty string.
* @param context
* The procedure handle where the internal procedure will be searched and executed.
*
* @return <code>true</code> if the event was registered.
*/
@Override
public logical setCallbackProcedure(character event, String proc, handle context)
{
return setCallbackProcedure(event, new character(proc), context);
}
/**
* Associate the internal procedure with the given web-services event.
* <p>
* This method returns false if the event name is not valid or if the procedure's context is
* not a valid handle.
* <p>
* For external procedures, this always shows an error.
*
* @param event
* The event name, must evaluate to one of the "REQUEST-HEADER" or the
* "RESPONSE-HEADER" strings.
* @param proc
* The internal procedure to be executed for this event. To remove a callback
* mapping, set the this parameter to the empty string.
* @param context
* The procedure handle where the internal procedure will be searched and executed.
*
* @return <code>true</code> if the event was registered.
*/
@Override
public logical setCallbackProcedure(String event, character proc, handle context)
{
return setCallbackProcedure(new character(event), proc, context);
}
/**
* Associate the internal procedure with the given web-services event.
* <p>
* This method returns false if the event name is not valid or if the procedure's context is
* not a valid handle.
* <p>
* For external procedures, this always shows an error.
*
* @param event
* The event name, must evaluate to one of the "REQUEST-HEADER" or the
* "RESPONSE-HEADER" strings.
* @param proc
* The internal procedure to be executed for this event. To remove a callback
* mapping, set the this parameter to the empty string.
* @param context
* The procedure handle where the internal procedure will be searched and executed.
*
* @return <code>true</code> if the event was registered.
*/
@Override
public logical setCallbackProcedure(character event, character proc, handle context)
{
final String msg =
"**The SET-CALLBACK-PROCEDURE attribute on the PROCEDURE widget has invalid arguments";
ErrorManager.recordOrShowError(4065, msg, false, false, false);
return new logical(false);
}
/**
* Retrieves the handle of the procedure that contains the internal procedure associated
* with the ABL callback for the specified event
*
* @param eventName
* The name of the event.
*
* @return a handle to the procedure that contains the callback procedure.
*/
@Override
public handle getCallbackProcContext(String eventName)
{
UnimplementedFeature.missing("GET-CALLBACK-PROC-CONTEXT(String event)");
return new handle();
}
/**
* Retrieves the name of the internal procedure associated with the ABL callback for the
* specified event.
*
* @param eventName
* The name of the event.
*
* @return the name of the internal procedure associated with specified event.
*/
@Override
public character getCallbackProcName(String eventName)
{
UnimplementedFeature.missing("GET-CALLBACK-PROC-NAME(String event)");
return new character();
}
/**
* Applies a callback procedure, which allows execution of a defined event without duplicating
* the event procedure definition.
*
* @param eventName
* The event whose callback will be called.
*
* @return {@code true} if operation is successful.
*/
@Override
public logical applyCallback(String eventName)
{
UnimplementedFeature.missing("APPLY-CALLBACK(String event)");
return new logical();
}
/**
* Check if the resource can veto the delete or not, before attempting the {@link #delete()} call.
*
* @param ref
* The exact handle holding the reference, on which the delete is attempted.
* @param explicit
* Flag indicating this is called via <code>DELETE OBJECT</code> from the application.
*
* @return <code>false</code> if the delete is vetoed.
*/
@Override
public boolean allowDelete(handle ref, boolean explicit)
{
return true;
}
/**
* Perform actual delete of this procedure, by calling {@link ProcedureManager#delete(Object, boolean)}.
* This will trigger a referent clear which won't happen necessarily now - it can be deferred
* to a specific block, moment at which the deferredDelete method will be fired.
*/
@Override
public void delete()
{
if (pm.delete(this.get(), true))
{
// cleanup after it
handle.removeResource(this);
}
// if this is an appserver REMOTE procedure handle, then the requester side is not informed
// about the handle deletion; only when deleting it from the requester side, the remote side
// will be informed
}
/**
* Implement the MuliDeletable interface; this resource is normally cleared at first delete.
* However, in specific scenario, this can be deleted again even if invalid. Thus postpone
* the deletion.
*
* @return <code>false</code> if this can't handle an invalid delete or <code>true</code> otherwise.
*/
@Override
public boolean handleMultipleDeletes()
{
return StaleProcedureManager.invalidateResource(referent);
}
/**
* Implements the DeferredDeletable interface. This will be called when this resource should be deleted
* for real - meaning that the referent should be removed. A simple delete will only cause an invalidation
* and a defer, while this will remove the referent.
*/
@Override
public void deferredDelete()
{
StaleProcedureManager.notifyResourceDelete(referent);
}
/**
* Returns the number of asynchronous requests.
*
* @return For non-proxy procedures, always 0.
*/
@Override
public integer getAsyncRequestCount()
{
return new integer(0);
}
/**
* Get the named events published by this procedure. This is a comma separated list of
* named events collected from the PUBLISH statements, where the named event is a hard-coded
* string, not a variable.
*
* @return The named events published by this procedure, or the empty string if none found.
*/
@Override
public character getPublishedEvents()
{
String pname = ProcedureManager.getAbsoluteName(referent);
return new character(SourceNameMapper.getPublishedEvents(pname));
}
/**
* Getter for the INSTANTIATING-PROCEDURE attribute.
* <p>
* The returned handle will refer a valid external procedure (persistent or not) or will be
* unknown, when this is a entry point procedure or in case its instantiating procedure was
* persistent and has been deleted.
*
* @return See above.
*/
@Override
public handle instantiatingProcedure()
{
return pm.resolveInstantiatingProcedure(pm.getInstantiatingProcedure(referent));
}
/**
* Displays "FILE-INFO is not a setable attribute for PROCEDURE widget" error message.
*
* @param name
* Not used.
*/
@Override
public void initFileInfo(character name)
{
ErrorManager.recordOrShowError(4052,
"FILE-NAME is not a setable attribute for PROCEDURE widget",
false);
}
/**
* Displays "FILE-INFO is not a setable attribute for PROCEDURE widget" error message.
*
* @param name
* Not used.
*/
@Override
public void initFileInfo(String name)
{
initFileInfo(new character(name));
}
}