GetProgramFunctionInfo function

Syntax

GetProgramFunctionInfo(ProgramId)

Where ProgramId is the following for PeopleCode user-defined functions:

RECORD.RecordName.FIELD.FieldName.METHOD.MethodName

Where ProgramId is the following for Component Interface user-defined methods:

COMPONENTINTERFACE.CIName.METHODS.Methods

Description

Use the GetProgramFunctionInfo function to determine the full signature and return values of a PeopleCode user-defined function, or a Component Interface method.

Parameters

Parameter Description

ProgramId

Specify the full name of the function or the Component Interface method, as a string.

Returns

An array of array of any.

There is one array for every function or method defined in the program. Each array contains the following information:

  1. The name of the function.

  2. The signature of the parameters as a comma-separated string (see additional information below.)

  3. The signature of the result (see result list below.)

  4. The annotation of the Doc tag.

  5. A boolean indicator of whether this function is to be exported (as indicated by the noexp tag).

  6. A boolean indicator of whether this function is permitted to be called by this user. This only makes sense for Functions defined as CI methods in Component Interface PeopleCode. The default value is True.

The parameters may be modified by the following values:

Value Description

?

An optional parameter.

*

A repeated parameter.

&

A parameter reference (PARM_NAME)

The possibly values of the result are as follows. Note the use of both lower and upper case letters.

Value Description

D

Dec

d

Date

S

String

A

Any

B

Boolean

V

None

t

Time

T

DateTime

I

Image

i

Integer

O

Object

f

Float

9

Number

x

Unknown

[<value>

Array

A single bracket indicates a single array. Two brackets indicates a two-dimensional array, three brackets a three-dimensional array, and so on.

The value following the bracket indicates the type of array. For example, [i indicates an array of integer, [[S indicates an array of array of string.

Example

In the following example, this code is associated with the record QE_ABSENCE_HIST, on the field QE_REASON, in the FieldChange event.

Function Update(&1 As string) Returns number NoExport
   Doc "this is some attached annotation"
   Return 1.23;
End-Function;
/* everything else . . */

The following PeopleCode program:

Local array of array of any &r;
&r = GetProgramFunctionInfo("RECORD.QE_ABSENCE_HIST.FIELD.QE_REASON.METHOD.Field
Change");

Returns a two-dimensional array with a single row that contains the following:

&r[1][1] – the name of the function “Update”

&r[1][2] – the signature of the parameter “S&”

&r[1][3] – the signature of the result “9”

&r[1][4] – the annotation of the doc tag “this is some attached annotation”

&r[1][5] – a boolean indicator of whether this function is to be exported. In this case it returns false.

The following example is used with a Component Interface program:

Function Update(&1 As string) Returns number NoExport
   Doc "this is some attached annotation"
   Return 1.23;
End-Function;

Function Updateagain(&1 As string) Returns number
   Doc "this is some more attached annotation"
   Return 1.23;
End-Function;

Local File &log;

Function LogText(&msg As string)
   If &log = Null Then
      Return
   End-If;
   &log.WriteLine(&msg);
End-Function;
Function CreateCI(&Name As string) Returns ApiObject
   Local ApiObject &CI;
   /** Get Component Interface **/
   &CI = %Session.GetCompIntfc(@("CompIntfc." | &Name));
   /* instantiate */
   &CI.PROCESSNAME = "AEMINITEST";
   &CI.PROCESSTYPE = "Application Engine";
   &CI.RUNCONTROLID = 99;
   &CI.Create();
   Return &CI;
End-Function;

Function DisplayProgramFuncInfo(&r As array of array of any)
   Local integer &i;
   For &i = 1 To &r.Len
      Local string &o;
      &o = &r [&i][1] | "(" | &r [&i][2] | ";" | &r [&i][3] | ") doc '" 
      | &r [&i][4] | "'";
      If &r [&i][5] = 0 Then
         &o = &o | " noexport ";
      Else
         &o = &o | " export ";
      End-If;
      If &r [&i][6] = 0 Then
         &o = &o | " no permission ";
      Else
         &o = &o | " permitted ";
      End-If;
      LogText(&o);
   End-For;
End-Function;

Function SetupParameters(&Names As array of string, &Sigs As array of string)
 Returns array of any
   Local array of any &p = CreateArrayAny();
   Local integer &i;
   /* could use the parameter name to get values out of a dom?? */
   /* Base types we could handle
//  D = Dec
//  S = String
//  d = Date
//  A = Any
//  B = Boolean
//  V = None
//  t = Time
//  T = DateTime
//  I = Image
//  O = Object
//  i = Integer
//  f = Float
//  9 = Number
//  x = Unknown
*/
   For &i = 1 To &Sigs.Len
      Local string &parName = RTrim(LTrim(&Names [&i + 1])); 
/* first name is create/get/?? */
      /* Here is where you'd get the value for this particular parameter 
 and then push it properly onto the parameter array */
      Evaluate Substring(&Sigs [&i], 1, 1)
      When = "D"
         &p.Push(1);
         Break;
      When = "S"
         &p.Push("String for " | &parName);
         Break;
      When = "9"
      When = "i"
         &p.Push(&i);
         Break;
      When-Other
         &p.Push("Unimplemented . . .");
      End-Evaluate
   End-For;
   Return &p;
End-Function;

Function CallUDMMethod(&ci As ApiObject, &funcInfo As array of array of any,
 &methodName As string) Returns any
   /* an example of calling a user defined method on a ci */
   /* 1. find it in the funcinfo */
   Local integer &i = 1;
   Local integer &nFuncs = &funcInfo.Len;
   While &i <= &nFuncs
      /* name should match and it should be exportable (the default) 
		 and the doc tag should have something in it 
		 and it should be permitted */
      If &funcInfo [&i][1] = &methodName And
            &funcInfo [&i][5] <> 0 And
            Len(&funcInfo [&i][4]) > 0 And
            &funcInfo [&i][6] <> 0 Then
         Break;
      End-If;
      &i = &i + 1;
   End-While;
   If &i > &nFuncs Then
      LogText("not found");
      Return False;
   End-If;
   /* 2. Next get the info necessary to call the function based on the signature
 info */
   Local string &parSignatures = &funcInfo [&i][2];
   Local boolean &bPars = False;
   Local array of any &Pars;
   If Len(&parSignatures) > 0 Then
      &bPars = True;
      Local array of string &parSignature = Split(&parSignatures, ",");
      Local array of string &parNames = Split(&funcInfo [&i][4], ","); 
/* first one should be Create/get/? */
      /* number of parameters should match number of parameter names  */
      If &parSignature.Len <> &parNames.Len - 1 Then
         LogText("length mismatch");
         Return False;
      End-If;
      &Pars = SetupParameters(&parNames, &parSignature);
   Else
      &Pars = CreateArrayAny();
   End-If;

   /* 3. Call the udm method with our parameters */
   Return &ci.InvokeMethodUDF(&methodName, &Pars);
End-Function;

QE_ABSENCE_HIST.QE_REASON.Value = ""; /* clean it up */
Local string &ciName = "PROCESSREQUEST";

Local ApiObject &CI = CreateCI(&ciName);

Local array of any &pars = CreateArrayAny("First parameter", 2);
/* check with variable for method name */
Local string &methodname = "FoxTest";
/* add in a bogus parameter  - tested - works - fails with false return :-( as per⇒
 usual in api objects*/
Local string &bogus = "bogus par";

&log = GetFile("C:\temp\junk\udflog.txt", "a", "UTF8", %FilePath_Absolute);
LogText("=====================================");
LogText("Result of direct call: " | &CI.InvokeMethodUDF(&methodname, &pars /* ,⇒
 &bogus */));
rem LogText("&ci: " | &CI);

/* do this the new way - at least model how a webservices Peoplecode⇒
 implementation could do it */
Local string &ciObjid = "COMPONENTINTERFACE." | &ciName | ".METHOD.Methods";
/* get the program information */
Local array of array of any &progInfo;
&progInfo = GetProgramFunctionInfo(&ciObjid);
/* returns a an array of arrays: an array for each function defined in the program.

Each row has the following ([i] = position i):
[1] = program name (string)
[2] = comma separated list of parameter signatures (string)
[3] = result signature (string)
[4] = text that was with the doc tag. Convention here is a comma separated list of⇒
 values:
    first item is one of either Create or Get, specifying what method has to be⇒
 called first
    second and subsequent items are the names of the parameters (this information⇒
 is not obtainable from the
    program information. These are the names to be exposed as the web service⇒
 parameter names

    e.g. the above function would have a doc like "Create, StringParameter,⇒
 NumericParameter"
[5] = an integer setting: 0=no export and 1=export (the default)
[6] = an integer setting indicating the permission for user to call this (only⇒
 applies to CI programs)
		0=no permission and 1=permitted (the default)

*/
DisplayProgramFuncInfo(&progInfo);
If &CI = Null Then
   &CI = CreateCI(&ciName);
End-If;
LogText("Result of indirect call: " | CallUDMMethod(&CI, &progInfo, &methodname));

Considerations Using Component Interfaces

Component Interfaces only support type conversion of primitive data types back and forth between PeopleCode values and those using inside Component Interface processing.

Component Interface processing traps all errors that occur inside the invocation of the Component Interface and on failure simply returns a false value.