OerequestInfo.java
/*
** Module : OerequestInfo.java
** Abstract : Implementation of the builtin class.
**
** Copyright (c) 2019-2025, Golden Code Development Corporation.
**
** -#- -I- --Date-- -------------------------------Description--------------------------------
** 001 CA 20190526 First version, stubs taken by converting the skeleton using FWD.
** 002 CA 20190812 Added LegacyResource annotation.
** 003 CA 20191024 Added method support levels and updated the class support level.
** 004 CA 20200427 Completed runtime.
** 005 CA 20210221 Fixed 'qualified', 'extent' and 'returns' annotations at the legacy
** signature.
** 006 HC 20230116 Replaced some handle usages with the actual wrapped resources for
** performance.
** 007 CA 20231113 The 'execute' method must be annotated with LegacySignature Type.Execute, and also can be
** dropped if is a no-op.
** 008 GBB 20240112 Support adapterType enum.
** 009 GBB 20250403 Javadoc fixes.
*/
/*
** 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.oo.lang;
import com.goldencode.p2j.util.*;
import com.goldencode.p2j.oo.applicationserver.*;
import static com.goldencode.p2j.util.BlockManager.*;
import static com.goldencode.p2j.report.ReportConstants.*;
import static com.goldencode.p2j.util.InternalEntry.Type;
/**
* Business logic (converted to Java from the 4GL source code
* in Progress/Lang/OERequestInfo.cls).
*
* Can be accessed in ABL with:
* <ul>
* <li>server-handle:REQUEST-INFO</li>
* <li>server-handle:RESPONSE-INFO</li>
* <li>async-request-handle:REQUEST-INFO<</li>
* <li>async-request-handle:RESPONSE-INFO<</li>
* </ul>
*
* Can be accessed in appserver with:
* <ul>
* <li>SESSION:CURRENT-REQUEST-INFO</li>
* <li>SESSION:CURRENT-RESPONSE-INFO</li>
* </ul>
*/
@LegacyResource(resource = "Progress.Lang.OERequestInfo")
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_STUB)
public final class OerequestInfo
extends BaseObject
{
/** The adapter type. */
private object<? extends AdapterTypes> adapterType = TypeFactory.object(AdapterTypes.class);
/** The agent ID. Only in multi-session agent appservers. */
private integer agentId = TypeFactory.integer();
/** The session ID. Only in multi-session agent appservers. */
private integer sessionId = TypeFactory.integer();
/** The thread ID. Only in multi-session agent appservers. */
private integer threadId = TypeFactory.integer();
/** The client context ID. */
private character clientContextId = TypeFactory.character();
/** The procedure name. */
private character procedureName = TypeFactory.character();
/** The request ID. */
private character requestId = TypeFactory.character();
/** The version info. */
private object<? extends OeversionInfo> versionInfo = TypeFactory.object(OeversionInfo.class);
/** The client principal. */
private handle clientPrincipal = TypeFactory.handle();
/**
* Default constructor. Sets only the {@link #versionInfo}.
*/
@LegacySignature(type = Type.CONSTRUCTOR)
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public void __lang_OerequestInfo_constructor__()
{
internalProcedure(this, "__lang_OerequestInfo_constructor__", new Block((Body) () ->
{
__lang_BaseObject_constructor__();
// AdapterType property: only SESSION:request
// ClientContextId property:
// - get/set, generated on the SERVER:request when SERVER is built
// - transported to the SESSION:request via CONNECT/RUN and read via SESSION:request.
// - SESSION:response will send it back
// RequestId property:
// - get, SESSION/SERVER:request/response, generated by the client and sent with each RUN
// ProcedureName property
// - only SESSION:request
// - the original (rel/full) path of the external program invoked by the client
// AgentId, SessionId, ThreadId:
// - set by appserver, SESSION:request/response, SERVER:response
// VersionInfo property:
// - r/o, REQUEST: ver of the client, RESPONSE: ver of the appserver
this.versionInfo.assign(SessionUtils.localVersionInfo());
// GetClientPrincipal and SetClientPrincipal
// - both are transported via each CONNECT/RUN
}));
}
/**
* Get the {@link #adapterType} field.
*
* @return See above.
*/
@LegacySignature(returns = "OBJECT", qualified = "Progress.ApplicationServer.AdapterTypes", type = Type.GETTER, name = "AdapterType")
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public object<? extends com.goldencode.p2j.oo.applicationserver.AdapterTypes> getAdapterType()
{
return function(this, "AdapterType", object.class, new Block((Body) () ->
{
returnNormal(adapterType);
}));
}
/**
* Get the {@link #agentId} field.
*
* @return See above.
*/
@LegacySignature(returns = "INTEGER", type = Type.GETTER, name = "AgentId")
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public integer getAgentId()
{
return function(this, "AgentId", integer.class, new Block((Body) () ->
{
returnNormal(agentId);
}));
}
/**
* Get the {@link #clientContextId} field.
*
* @return See above.
*/
@LegacySignature(returns = "CHARACTER", type = Type.GETTER, name = "ClientContextId")
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public character getClientContextId()
{
return function(this, "ClientContextId", character.class, new Block((Body) () ->
{
returnNormal(clientContextId);
}));
}
/**
* Set the {@link #clientContextId} field.
*
* @param _var
* The client context ID.
*/
@LegacySignature(type = Type.SETTER, name = "ClientContextId", parameters =
{
@LegacyParameter(name = "var", type = "CHARACTER", mode = "INPUT")
})
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public void setClientContextId(final character _var)
{
character var = TypeFactory.initInput(_var);
internalProcedure(this, "ClientContextId", new Block((Body) () ->
{
clientContextId.assign(var);
}));
}
/**
* Get the {@link #procedureName} field.
*
* @return See above.
*/
@LegacySignature(returns = "CHARACTER", type = Type.GETTER, name = "ProcedureName")
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public character getProcedureName()
{
return function(this, "ProcedureName", character.class, new Block((Body) () ->
{
returnNormal(procedureName);
}));
}
/**
* Get the {@link #requestId} field.
*
* @return See above.
*/
@LegacySignature(returns = "CHARACTER", type = Type.GETTER, name = "RequestId")
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public character getRequestId()
{
return function(this, "RequestId", character.class, new Block((Body) () ->
{
returnNormal(requestId);
}));
}
/**
* Get the {@link #sessionId} field.
*
* @return See above.
*/
@LegacySignature(returns = "INTEGER", type = Type.GETTER, name = "SessionId")
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public integer getSessionId()
{
return function(this, "SessionId", integer.class, new Block((Body) () ->
{
returnNormal(sessionId);
}));
}
/**
* Get the {@link #threadId} field.
*
* @return See above.
*/
@LegacySignature(returns = "INTEGER", type = Type.GETTER, name = "ThreadId")
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public integer getThreadId()
{
return function(this, "ThreadId", integer.class, new Block((Body) () ->
{
returnNormal(threadId);
}));
}
/**
* Get the {@link #versionInfo} field.
*
* @return See above.
*/
@LegacySignature(returns = "OBJECT", qualified = "Progress.Lang.OEVersionInfo", type = Type.GETTER, name = "VersionInfo")
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public object<? extends com.goldencode.p2j.oo.lang.OeversionInfo> getVersionInfo()
{
return function(this, "VersionInfo", object.class, new Block((Body) () ->
{
returnNormal(versionInfo);
}));
}
/**
* Get the {@link #clientPrincipal}.
*
* @return See above.
*/
@LegacySignature(returns = "HANDLE", type = Type.METHOD, name = "GetClientPrincipal")
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public handle getClientPrincipal()
{
return function(this, "GetClientPrincipal", handle.class, new Block((Body) () ->
{
returnNormal(this.clientPrincipal);
}));
}
/**
* Get the {@link #clientPrincipal}.
*
* @return See above.
*/
public ClientPrincipal getClientPrincipalNative()
{
return (ClientPrincipal) this.clientPrincipal.getResource();
}
/**
* Set the {@link #clientPrincipal}. This deletes any other instance it may reference via the
* {@link #clientPrincipal}.
*
* @param _h
* The client principal handle.
*
* @return <code>true</code> if the assign was possible.
*/
@LegacySignature(returns = "LOGICAL", type = Type.METHOD, name = "SetClientPrincipal", parameters =
{
@LegacyParameter(name = "h", type = "HANDLE", mode = "INPUT")
})
@LegacyResourceSupport(supportLvl = CVT_LVL_FULL|RT_LVL_FULL)
public logical setClientPrincipal(final handle _h)
{
handle h = TypeFactory.initInput(_h);
return function(this, "SetClientPrincipal", logical.class, new Block((Body) () ->
{
if (h.isUnknown())
{
if (this.clientPrincipal._isValid())
{
HandleOps.delete(this.clientPrincipal);
this.clientPrincipal.setUnknown();
}
returnNormal(true);
}
else if (!(h.getResource() instanceof ClientPrincipal) || !h._isValid())
{
returnNormal(false);
}
this.clientPrincipal.assign(h);
returnNormal(true);
}));
}
/**
* Set the {@link #requestId}. This is not a legacy setter!
*
* @param requestId
* The request ID.
*/
public void setRequestId(String requestId)
{
this.requestId.assign(requestId);
}
/**
* Initialize this instance with the specified values for each field.
*
* @param procedureName
* The procedure name.
* @param clientContextId
* The client context ID.
* @param requestId
* The request ID.
* @param versionInfo
* The version info, in the [major, minor, maint] format.
* @param clientType
* The client type.
* @param agentId
* The agent ID.
* @param sessionId
* The session ID.
* @param threadId
* The thread ID.
* @param clientPrincipal
* The serialized client principal.
*/
public void initialize(String procedureName,
String clientContextId,
String requestId,
String[] versionInfo,
String clientType,
Integer agentId,
Integer sessionId,
Integer threadId,
byte[] clientPrincipal)
{
this.procedureName.assign(procedureName);
this.clientContextId.assign(clientContextId);
this.requestId.assign(requestId);
this.versionInfo.assign(OeversionInfo.newInstance(versionInfo == null ? null : versionInfo[0],
versionInfo == null ? null : versionInfo[1],
versionInfo == null ? null : versionInfo[2],
clientType));
this.agentId.assign(agentId);
this.sessionId.assign(sessionId);
this.threadId.assign(threadId);
if (this.clientPrincipal._isValid())
{
HandleOps.delete(this.clientPrincipal);
}
if (clientPrincipal == null)
{
this.clientPrincipal.setUnknown();
}
else
{
ClientPrincipal.create(this.clientPrincipal);
this.clientPrincipal.unwrapClientPrincipal().importPrincipal(new raw(clientPrincipal));
}
}
/**
* Initialize this instance from the specified reference, by copying the state.
*
* @param req
* The request instance to initialize from.
* @param request
* Flag indicating if the current instance is for a request - if so, set the
* {@link #procedureName}.
*/
public void initialize(OerequestInfo req, boolean request)
{
if (request)
{
// do not set it in response
this.procedureName.assign(req.procedureName);
}
else
{
this.procedureName.setUnknown();
}
this.clientContextId.assign(req.clientContextId);
this.requestId.assign(req.requestId);
this.agentId.assign(req.agentId);
this.sessionId.assign(req.sessionId);
this.threadId.assign(req.threadId);
this.versionInfo.assign(SessionUtils.localVersionInfo());
if (req.clientPrincipal._isValid())
{
this.clientPrincipal.set(((ClientPrincipal) req.clientPrincipal.getResource()).clone());
}
}
/**
* Obtain an array representation of this instance, for serialization purposes.
*
* @return The instance fields, in the [adapterType, procedureName, clientContextId, requestId,
* agentId, sessionId, threadId, [major, minor, maint, clientType], clientPrincipal]
* order.
*/
public Object[] toArray()
{
OeversionInfo ver = versionInfo.ref();
Object[] res = new Object[9];
res[0] = adapterType._isValid() ? adapterType.ref().toLegacyString() : null;
res[1] = procedureName.getValue();
res[2] = clientContextId.getValue();
res[3] = requestId.getValue();
res[4] = agentId.toJavaIntegerType();
res[5] = sessionId.toJavaIntegerType();
res[6] = threadId.toJavaIntegerType();
res[7] = new String[]
{
ver.getOemajorVersion().getValue(),
ver.getOeminorVersion().getValue(),
ver.getOemaintVersion().getValue(),
ver.getOeclientType().getValue()
};
res[8] = null;
if (clientPrincipal._isValid())
{
raw r = ((ClientPrincipal) clientPrincipal.getResource()).exportPrincipal();
res[8] = r.getByteArray();
}
return res;
}
/**
* Initialize this instance from the given array representation (from a previous
* {@link #toArray()} call).
*
* @param arr
* The serialized instance, as was returned by {@link #toArray()}.
*/
public void fromArray(Object[] arr)
{
adapterType.assign(arr[0]);
procedureName.assign(arr[1]);
clientContextId.assign(arr[2]);
requestId.assign(arr[3]);
agentId.assign(arr[4]);
sessionId.assign(arr[5]);
threadId.assign(arr[6]);
String[] ver = (String[]) arr[7];
versionInfo.assign(OeversionInfo.newInstance(ver[0], ver[1], ver[2], ver[3]));
if (clientPrincipal._isValid())
{
HandleOps.delete(clientPrincipal);
}
byte[] cp = (byte[]) arr[8];
if (cp == null)
{
this.clientPrincipal.setUnknown();
}
else
{
ClientPrincipal.create(clientPrincipal);
((ClientPrincipal) clientPrincipal.getResource()).importPrincipal(new raw(cp));
}
}
}