RPL Implementation
An RPL user exit implementation is stored in a RO_EXECUTABLE item named DateCheckUserExitSample. The table lists the attributes that must be filled in the RO_EXECUTABLE item.
| Attribute | Value |
|---|---|
RO_EXEC-CONTEXT
|
RPL or AP-CC |
RO_EXEC-LANGUAGE
|
RPL |
SOURCE
|
The RPL executable code |
Set the RO_EXEC-CONTEXT to RPL when the code is written in plain RPL or no access to the database is necessary. Set the RO_EXEC-CONTEXT to AP-CC if you are using AutoPilot core classes or the context is a subject area. This sample program uses the context RPL.
Since the source attribute must contain executable RPL code, the user exit is implemented in a procedure to be called from the source attribute. The SOURCE attribute contains only two lines of RPL code: A call to an RPL procedure and a $exit statement to deliver the return code from the procedure. For example:
#DateCheckUserExitSample
#$exit :retcode
The following source code is a sample implementation of the RPL procedure DateCheckUserExitSample.
;/**
; * Sample implementation demonstrating how to implement a user exit.
; * This sample is an attribute contents user exit for text and value attributes.
; * It shows how constraint checks can be implemented. This program
; * checks whether the supplied date is within a specified date range.
; */
;
; // This is an ON_SAVE attribute user exit.
#$mapget j_env s j_uetype arguetp
if (:arguetp <> on_save) (
; // Force an exception and return a message, action advice value and a
; // level value to the UserExitException. These values can be retrieved
; // by calling UserExitException.getExceptionText(),
; // getExceptionActionAdvice(), getExceptionLevel().
#$redln j_env
#$concat argmsg @UserExit@ only@ applicable@ for@ type@ ON_SAVE
#$mapput s j_msg :argmsg
#$mapput s j_actadv cancel
#$mapput s j_level error
#$quit
#$exit false
)
;
; // Get the range of valid dates from the user exit arguments (argv).
#$mapget j_env s j_argv argargv
#$mapget :argargv s @begin argsbeg
#$mapget :argargv s @end argsend
#datechecktonumber :argsbeg
#$make argdbeg :retcode
if (:argdbeg = false) (
#$redln j_env
#$concat argmsg @Wrong@ begin@ date@ format.@ @(MM/dd/yyyy@).
#$mapput s j_msg :argmsg
#$mapput s j_actadv cancel
#$mapput s j_level error
#$quit
#$exit false
)
#datechecktonumber :argsend
#$make argdend :retcode
if (:argdend = false) (
#$redln j_env
#$concat argmsg @Wrong@ end@ date@ format.@ @(MM/dd/yyyy@).
#$mapput s j_msg :argmsg
#$mapput s j_actadv cancel
#$mapput s j_level error
#$quit
#$exit false
)
;
; // Get the attribute contents.
#$mapget j_env s j_cont argcont
#$redln :argcont
#$find $
if (:$ln = 1) (
#$strl argdate 1
#datechecktonumber :argdate
#$make argdate :retcode
) else
#$make argdate false
#$quit
if (:argdate = false) (
#$redln j_env
#$mapput s j_msg @Wrong@ date@ format.@ @(MM/dd/yyyy@)
#$mapput s j_actadv retry
#$mapput s j_level warn
#$quit
#$exit false
)
;
; // Check the date.
if ((:argdate < :argdbeg) or (:argdate > :argdend)) (
#$redln j_env
#$concat argmsg @Date@ must@ be@ between@ :argsbeg @ and@ :argsend .
#$mapput s j_msg :argmsg
#$mapput s j_actadv retry
#$mapput s j_level info
#$quit
#$exit false
)
#$exit true
The following example is the source code of the procedure DateCheckToNumber that is called by DateCheckUserExitSample.
; /**
; * Check date format and convert it to a number.
; * Format: MM/dd/yyyy
; * Arg1: The date in the specified format.
; * Return: yyyyMMdd
; */
;
#$redln argwa
#$lputln :arg1
;
#$strl argmonth 1 2 1
if (:retcode <> T)
#$exit false
#$make argtmp :argmonth
#$add1 argtmp
if (:retcode <> T)
#$exit false
;
#$strl argdelim 3 1 1
if ((:retcode <> T) or (:argdelim <> /))
#$exit false
;
#$strl argday 4 2 1
if (:retcode <> T)
#$exit false
#$make argtmp :argmonth
#$add1 argtmp
if (:retcode <> T)
#$exit false
;
#$strl argdelim 6 1 1
if ((:retcode <> T) or (:argdelim <> /))
#$exit false
;
#$strl argyear 7 4 1
if (:retcode <> T)
#$exit false
#$make argtmp :argmonth
#$add1 argtmp
if (:retcode <> T)
#$exit false
;
#$concat argdate :argyear :argmonth :argday
#$exit :argdate