Skip to content

Instantly share code, notes, and snippets.

@vbalashi
Last active September 24, 2025 09:32
Show Gist options
  • Select an option

  • Save vbalashi/c825b7287a240ad3d7f8164ee8c0b0af to your computer and use it in GitHub Desktop.

Select an option

Save vbalashi/c825b7287a240ad3d7f8164ee8c0b0af to your computer and use it in GitHub Desktop.

Lua Functions and Methods Reference

This section describes the functions and methods that you can use in your Lua scripts.

NiFi Ingest includes Lua version 5.3.6. Any Lua modules that you use must be compatible with this version.

General Functions

Function Description
abs_path Returns the supplied path as an absolute path.
base64_decode Decodes a base64-encoded string.
base64_encode Base64-encodes a string.
convert_date_time Converts date and time formats.
convert_encoding Converts the encoding of a string from one character encoding to another.
copy_file Copies a file.
create_path Creates the specified directory tree.
create_uuid Creates a universally unique identifier.
date_time_now Returns the current date and time in the specified date format.
decrypt Decrypts a string that was encrypted using the encrypt function.
decrypt_security_field Decrypts a supplied ACL string.
delete_file Deletes a file.
delete_path Deletes a specified directory, but only if it is empty.
doc_tracking Raises a document tracking event for a document.
encrypt Encrypts a string.
encrypt_security_field Encrypts the ACL.
extract_date Searches a string for a date and returns the date.
file_setdates Modifies the properties of a file (for example created date, last modified date).
fingerprint_string Generates a list of fingerprints from an input string.
get_config Loads a configuration file.
get_log (Deprecated) Returns a LuaLog object that provides the capability to write log messages.
get_log Returns a LuaLog object that provides the capability to write log messages.
get_log_service Obtains a LuaLogService object, from which you can obtain a LuaLog object that you can use to write messages to a log file.
getcwd Returns the current working directory of the application.
gobble_whitespace Reduces multiple adjacent while spaces.
hash_file Hashes a file using the SHA1 or MD5 algorithm.
hash_string Hashes a string.
is_dir Checks if the supplied path is a directory.
log Appends log messages to a file.
lower_case_utf8 Converts a UTF-8 string to lower case.
move_file Moves a file.
parse_csv Parse comma-separated values into individual strings.
parse_document_csv Parse a CSV file into documents and call a function on each document.
parse_document_idx Parses an IDX file into documents and calls a function on each document.
parse_document_idx Parses an IDX file, or a string of IDX data, and returns a LuaDocument.
parse_document_idx Parses an IDX file, or a string of IDX data, into documents and calls a function on each document.
parse_document_xml Parses an XML file into documents and calls a function on each document.
parse_document_xml Parses an XML file, or a string of XML data, and returns a LuaDocument.
parse_document_xml Parses an XML file, or a string of XML data, into documents and calls a function on each document.
parse_json Parse a string of JSON data and return a LuaJsonValue.
parse_json_array Parse a string of JSON data (that is a JSON array) and a return a LuaJsonArray.
parse_json_object Parse a string of JSON data (that is a JSON object) and return a LuaJsonObject.
parse_xml Parse XML string to a LuaXmlDocument.
password_strength Evaluates the strength of a password.
regex_match Tests whether an input string matches a regular expression.
regex_replace_all Searches a string for matches to a regular expression, and replaces the matches.
regex_search Performs a regular expression search on a string.
script_path Returns the path and file name of the script that is running.
send_aci_action Sends a query to an ACI server.
send_aci_command Sends a query to an ACI server.
send_and_wait_for_async_aci_action Sends a query to an ACI server and then waits for the action to finish. Use this method for sending asynchronous actions so that the action response is returned instead of a token.
send_http_request Sends an HTTP request.
sleep Pauses the running thread.
unzip_file Extracts the contents of a zip file.
upper_case_utf8 Converts a UTF-8 string to upper case.
url_escape Percent-encode a string.
url_unescape Replaces URL escaped characters and returns a standard string.
xml_encode Takes a string and encodes it using XML escaping.
zip_file Zips the supplied path (file or directory).

abs_path

The abs_path function returns the supplied path as an absolute path.

Syntax
abs_path( path )
Arguments
Argument Description
path (string) A relative path.
Returns

(String). A string containing the supplied path as an absolute path.

base64_decode

Decodes a base64-encoded string.

Syntax
base64_decode( input )
Arguments
Argument Description
input (string) The string to decode.
Returns

(String). The decoded string.

If the input is not a valid base64-encoded string, the function returns nil.

base64_encode

Base64-encodes a string.

Syntax
base64_encode( input )
Arguments
Argument Description
input (string) The string to base64-encode.
Returns

(String). A base64-encoded string.

convert_date_time

Converts date and time formats. All date and time input is treated as local time unless it contains explicit time zone information.

The InputFormatCSV and OutputFormat arguments specify date and time formats, and accept the following values:

  • AUTNDATE. 1 to a maximum of 10 digits. This format covers the epoch range (1 January 1970 to 19 January 2038) to a resolution of one second, and dates between 30 October 1093 BC and 26 October 3058 to a resolution of one minute.

  • date formats that you specify using one or more of the following:

    YY Year (2 digits). For example, 99, 00, 01 and so on.
    YYYY Year (4 digits). For example, 1999, 2000, 2001 and so on.
    #YY+ Year (2 or 4 digits). If you provide 2 digits, then it uses the YY format. If you provide 4 digits, it uses the YYYY format. For example, it interprets 07 as 2007 AD and 1007 as 1007 AD.
    #Y Year (1 to a maximum of 16 digits) and can be followed by AD or BC. An apostrophe (') immediately before the year denotes a truncated year. For example, 2008, '97 (interpreted as 1997), 97 (interpreted as 97 AD), '08 (interpreted as 2008), 2008 AD and 200 BC. A truncated year with a BC identifier is invalid ('08 BC).
    #FULLYEAR Year (1 to a maximum of 16 digits). For example 8, 98, 108, 2008, each of which is taken literally. The year is taken relative to the common EPOCH (0AD).
    #ADBC Time Period. For example, AD, CE, BC, BCE or any predefined list of EPOCH indicators. Typically, the year specified using the above Year formats is interpreted as un-truncated and relative to the EPOCH. For example, 84 AD is interpreted as 1984 AD and 84 BC is interpreted as 84 BC. The only exception to this is when you use both #YY+ and #ADBC. In this case, the format is interpreted as un-truncated even if the year was set to truncated by #YY+. For example, 99 AD is interpreted as the year 99 AD. OpenText recommends you use only YY, YYYY or #FULLYEAR with #ADBC.
    LONGMONTH A long month, for example, January, February and so on.
    SHORTMONTH A short month, for example, Jan, Feb and so on.
    MM Month (2 digits). For example, 01, 10, 12 and so on.
    M+ Month (1 or 2 digits). For example, 1,2,3,10 and so on.
    DD Day (2 digits). For example, 01, 02, 03, 12, 23 and so on.
    D+ Day (1 or 2 digits). For example, 1, 2, 12, 13, 31 and so on.
    LONGDAY 2 digits with a postfix. For example, 1st, 2nd and so on.
    HH Hour (2 digits). For example, 01, 12, 13 and so on.
    H+ Hour (1 or 2 digits).
    NN Minute (2 digits).
    N+ Minute (1 or 2 digits).
    SS Second (2 digits).
    S+ Second (1 or 2 digits).
    ZZZ Time Zone, for example, GMT, EST, PST, and so on.
    ZZZZZ Time Difference (1 to 9 digits). For example, +04 denotes 4 hours ahead of UTC. Other examples include +4, +04, +0400, +0400 MSD (the string MSD is ignored). A further example is +030, in this case the time differences is interpreted as 30 minutes.
    #PM AM or PM indicator (2 characters). For example, 2001/09/09 02:46:40 pm
    #S A space

The following table shows some example date and time formats:

Date and time format string Example date
DD/MM/YYYY 09/05/2013
D+ SHORTMONTH YYYY 2 Jan 2001
D+ LONGMONTH YYYY HH:NN:SS ZZZZZ 17 August 2003 10:41:07 -0400
Syntax
convert_date_time( Input, InputFormatCSV, OutputFormat )
Arguments
Argument Description
Input (string) The date and time to convert.
InputFormatCSV (string) A comma-separated list of the possible date and time formats of the input.
OutputFormat (string) The format of the date and time to output.
Returns

(String). A string containing the date and time in the desired format.

convert_encoding

Converts the encoding of a string from one character encoding to another.

Syntax
convert_encoding( input, encodingTo, encodingTables [, encodingFrom])
Arguments
Argument Description
input (string) The string to convert.
encodingTo (string) The character encoding to convert to (same as IDOL encoding names).
encodingTables (string) The path to the conversion tables.
encodingFrom (string) The character encoding to convert from. The default is “UTF8”.
Returns

(String). A string, using the specified character encoding.

copy_file

Copies a file.

Syntax
copy_file( src, dest [, overwrite] )
Arguments
Argument Description
src (string) The source file.
dest (string) The destination path and file name.
overwrite (boolean) A boolean that specifies whether to copy the file if the destination file already exists. If this argument is false and the file already exists, the copy operation fails. The default is true, which means that the existing file is overwritten.
Returns

(Boolean). A Boolean, true to indicate success or false for failure.

create_path

Creates the specified directory tree.

Syntax
create_path( path )
Arguments
Argument Description
path (string) The path to create.

create_uuid

Creates a universally unique identifier.

Syntax
create_uuid()
Returns

(String). A string containing the universally unique identifier.

date_time_now

The date_time_now function gets the current date and time in the specified date format.

Date formats

YY Year (2 digits). For example, 99, 00, 01 and so on.
YYYY Year (4 digits). For example, 1999, 2000, 2001 and so on.
#YY+ Year (2 or 4 digits). If you provide 2 digits, then it uses the YY format. If you provide 4 digits, it uses the YYYY format. For example, it interprets 07 as 2007 AD and 1007 as 1007 AD.
#Y Year (1 to a maximum of 16 digits) and can be followed by AD or BC. An apostrophe (') immediately before the year denotes a truncated year. For example, 2008, '97 (interpreted as 1997), 97 (interpreted as 97 AD), '08 (interpreted as 2008), 2008 AD and 200 BC. A truncated year with a BC identifier is invalid ('08 BC).
#FULLYEAR Year (1 to a maximum of 16 digits). For example 8, 98, 108, 2008, each of which is taken literally. The year is taken relative to the common EPOCH (0AD).
#ADBC Time Period. For example, AD, CE, BC, BCE or any predefined list of EPOCH indicators. Typically, the year specified using the above Year formats is interpreted as un-truncated and relative to the EPOCH. For example, 84 AD is interpreted as 1984 AD and 84 BC is interpreted as 84 BC. The only exception to this is when you use both #YY+ and #ADBC. In this case, the format is interpreted as un-truncated even if the year was set to truncated by #YY+. For example, 99 AD is interpreted as the year 99 AD. OpenText recommends you use only YY, YYYY or #FULLYEAR with #ADBC.
LONGMONTH A long month, for example, January, February and so on.
SHORTMONTH A short month, for example, Jan, Feb and so on.
MM Month (2 digits). For example, 01, 10, 12 and so on.
M+ Month (1 or 2 digits). For example, 1,2,3,10 and so on.
DD Day (2 digits). For example, 01, 02, 03, 12, 23 and so on.
D+ Day (1 or 2 digits). For example, 1, 2, 12, 13, 31 and so on.
LONGDAY 2 digits with a postfix. For example, 1st, 2nd and so on.
HH Hour (2 digits). For example, 01, 12, 13 and so on.
H+ Hour (1 or 2 digits).
NN Minute (2 digits).
N+ Minute (1 or 2 digits).
SS Second (2 digits).
S+ Second (1 or 2 digits).
ZZZ Time Zone, for example, GMT, EST, PST, and so on.
ZZZZZ Time Difference (1 to 9 digits). For example, +04 denotes 4 hours ahead of UTC. Other examples include +4, +04, +0400, +0400 MSD (the string MSD is ignored). A further example is +030, in this case the time differences is interpreted as 30 minutes.
#PM AM or PM indicator (2 characters). For example, 2001/09/09 02:46:40 pm
#S A space
Syntax
date_time_now( format, gmt )
Arguments
Argument Description
format (string) A date format string that specifies the format of the returned string.
gmt (boolean, default false) Specifies whether to return the current time in GMT rather than local time. NOTE: The time zone values (ZZZ and ZZZZZ) in the format string always refer to the local time zone. If you set this argument to true, OpenText recommends omitting these from the format string.
Returns

String. The current date and time.

Examples
--Return value in local time
print (date_time_now("YYYY-MM-DD HH:NN:SS ZZZ"))

--Return value in GMT
print (date_time_now("YYYY-MM-DD HH:NN:SS", true))

decrypt

The decrypt function decrypts a string that was encrypted using the encrypt function.

Syntax
decrypt( content )
Arguments
Argument Description
content (string) The string to decrypt.
Returns

(String). The decrypted string.

decrypt_security_field

The decrypt_security_field function decrypts a supplied ACL string.

This function is similar to the decrypt function, but is intended for use with Access Control Lists (ACLs) which usually contain multiple encrypted strings with delimiters such as :U:,:NU:, and commas.

Syntax
decrypt_security_field( acl [, regex [, regex]] )
Arguments
Argument Description
acl (string) An encrypted Access Control List string.
regex (string) Any additional arguments that you pass to the function are taken as a list of regular expressions. The capturing groups in these regular expressions specify the parts of the string to decrypt. If you supply your own regular expression(s) the default ones listed below are not used: ``` (?:^
Returns

(String). The decrypted string.

Examples

The following example shows how to decrypt the standard AUTONOMYMETADATA document field:

local decrypted = decrypt_security_field(document:getFieldValue("AUTONOMYMETADATA"))

The following example shows how to specify custom regular expressions for decrypting parts of the input string:

local decrypted = decrypt_security_field(document:getFieldValue("AUTONOMYMETADATA"),
                                               ":U:([^:)]*)", ":G:([^:)]*)" )

delete_file

Deletes a file.

Syntax
delete_file( path )
Arguments
Argument Description
path (string) The path and filename of the file to delete.
Returns

(Boolean). A boolean, true to indicate success or false for failure.

delete_path

The delete_path function deletes the specified directory, but only if it is empty.

Syntax
delete_path( path )
Arguments
Argument Description
path (string) The empty directory to delete.
Returns

Nothing.

Example
delete_path( "C:\MyFolder\AnotherFolder\" )

doc_tracking

The doc_tracking function raises a document tracking event for a document.

Syntax
doc_tracking( document , eventName [, eventMetadata] [, reference] )
Arguments
Argument Description
document (LuaDocument) The document to track.
eventName (string) The event name. You can type a description of the event.
eventMetadata (table) A table of key-value pairs that contain metadata for the document tracking event.
reference (string) The document reference. You can set this parameter to override the document reference used.
Returns

(Boolean). A Boolean that indicates whether the event was raised successfully.

Example
local ref=document:getReference()

doc_tracking(document, "The document has been processed",
      {myfield="myvalue", anotherfield="anothervalue"}, ref )

encrypt

The encrypt function encrypts a string and returns the encrypted string. It uses the same encryption method as ACL encryption.

Syntax
encrypt( content )
Arguments
Argument Description
content (string) The string to encrypt.
Returns

(String). The encrypted string.

encrypt_security_field

The encrypt_security_field function returns the encrypted form of the supplied ACL string.

This function is similar to the encrypt function, but is intended for use with Access Control Lists (ACLs). The function encrypts user and group names, but not delimiters such as :U:,:NU:, and the commas in comma-separated lists of users and groups.

Syntax
encrypt_security_field( acl [, regex [, regex]] )
Arguments
Argument Description
acl (string) An Access Control List string.
regex (string) Any additional arguments that you pass to the function are taken as a list of regular expressions. The capturing groups in these regular expressions specify the parts of the string to encrypt. If you supply your own regular expression(s) the default ones listed below are not used: ``` (?:^
Returns

(String). An encrypted string.

extract_date

The extract_date function searches a string for a date and returns the date. This function uses standard IDOL date formats. All date and time input is treated as local time unless it contains explicit time zone information.

The following table describes the standard IDOL date formats:

YY Year (2 digits). For example, 99, 00, 01 and so on.
YYYY Year (4 digits). For example, 1999, 2000, 2001 and so on.
#YY+ Year (2 or 4 digits). If you provide 2 digits, then it uses the YY format. If you provide 4 digits, it uses the YYYY format. For example, it interprets 07 as 2007 AD and 1007 as 1007 AD.
#Y Year (1 to a maximum of 16 digits) and can be followed by AD or BC. An apostrophe (') immediately before the year denotes a truncated year. For example, 2008, '97 (interpreted as 1997), 97 (interpreted as 97 AD), '08 (interpreted as 2008), 2008 AD and 200 BC. A truncated year with a BC identifier is invalid ('08 BC).
#FULLYEAR Year (1 to a maximum of 16 digits). For example 8, 98, 108, 2008, each of which is taken literally. The year is taken relative to the common EPOCH (0AD).
#ADBC Time Period. For example, AD, CE, BC, BCE or any predefined list of EPOCH indicators. Typically, the year specified using the above Year formats is interpreted as un-truncated and relative to the EPOCH. For example, 84 AD is interpreted as 1984 AD and 84 BC is interpreted as 84 BC. The only exception to this is when you use both #YY+ and #ADBC. In this case, the format is interpreted as un-truncated even if the year was set to truncated by #YY+. For example, 99 AD is interpreted as the year 99 AD. OpenText recommends you use only YY, YYYY or #FULLYEAR with #ADBC.
LONGMONTH A long month, for example, January, February and so on.
SHORTMONTH A short month, for example, Jan, Feb and so on.
MM Month (2 digits). For example, 01, 10, 12 and so on.
M+ Month (1 or 2 digits). For example, 1,2,3,10 and so on.
DD Day (2 digits). For example, 01, 02, 03, 12, 23 and so on.
D+ Day (1 or 2 digits). For example, 1, 2, 12, 13, 31 and so on.
LONGDAY 2 digits with a postfix. For example, 1st, 2nd and so on.
HH Hour (2 digits). For example, 01, 12, 13 and so on.
H+ Hour (1 or 2 digits).
NN Minute (2 digits).
N+ Minute (1 or 2 digits).
SS Second (2 digits).
S+ Second (1 or 2 digits).
ZZZ Time Zone, for example, GMT, EST, PST, and so on.
ZZZZZ Time Difference (1 to 9 digits). For example, +04 denotes 4 hours ahead of UTC. Other examples include +4, +04, +0400, +0400 MSD (the string MSD is ignored). A further example is +030, in this case the time differences is interpreted as 30 minutes.
#PM AM or PM indicator (2 characters). For example, 2001/09/09 02:46:40 pm
#S A space

The following table shows some example date and time formats:

Date and time format string Example date
DD/MM/YYYY 09/05/2013
D+ SHORTMONTH YYYY 2 Jan 2001
D+ LONGMONTH YYYY HH:NN:SS ZZZZZ 17 August 2003 10:41:07 -0400
Syntax
extract_date( input, formatCSV, outputFormat )
Arguments
Argument Description
input (string) The string that you want to search for a date.
formatCSV (string) A comma-separated list of the possible date and time formats for dates contained in the input.
outputFormat (string) The format for the output.
Returns

(String). A string containing the date and time in the desired format.

Example

The following example would return the value "1989/01/14":

extract_date("This string contains a date 14/01/1989 somewhere", "DD/YYYY/MM,DD/MM/YYYY", "YYYY/MM/DD")

file_setdates

The file_setdates function sets the metadata for the file specified by path. If the format argument is not specified, the dates must be specified in seconds since the epoch (1st January 1970).

Syntax
file_setdates( path, created, modified, accessed [, format] )
Arguments
Argument Description
path (string) The path or filename of the file.
created (string) The date created (Windows only).
modified (string) The date modified.
accessed (string) The date last accessed.
format (string) The format of the dates supplied. The format parameter uses the same values as other IDOL components. The default is "EPOCHSECONDS"
Returns

(Boolean). A Boolean indicating whether the operation was successful.

fingerprint_string

The fingerprint_string function generates a list of fingerprints from an input string. These fingerprints can be compared with fingerprints generated from a different string to ascertain whether any parts of the strings match.

This function is intended to process document-sized portions of text. It returns multiple fingerprints because the input is divided into shorter sections (chunks) before the fingerprints are generated, so that you can find matches between two strings that are not identical but do contain common chunks of content.

Syntax
fingerprint_string( input[, min_chars[, mask_size[, num_bytes]]] )
Arguments
Argument Description
input (string) The input string to generate fingerprints from.
min_chars (integer) The minimum chunk size, in UTF-8 characters. The default value is 10.
mask_size (integer) Determines the frequency at which chunks are generated from the input. Increasing the value by one should approximately halve the number of chunks. Decreasing the value by one should approximately double the number of chunks. Specify a value from 1 to 31. The default value is 8.
num_bytes (integer) The length of the substring to check when calculating string chunk boundaries. OpenText recommends using the default value, which is 48.
Returns

(strings). One or more strings.

Example

To map the return values to a table, surround the function call with braces. For example:

local fingerprints = { fingerprint_string("here is the input string") };

get_config

The get_config function loads a configuration file.

Configuration files are cached after the first call to get_config, to avoid unnecessary disk I/O in the likely event that the same configuration is accessed frequently by subsequent invocations of the Lua script. One cache is maintained per Lua state, so the maximum number of reads for a configuration file is equal to the number of threads that run Lua scripts.

Syntax
get_config( path )
Arguments
Argument Description
path (string) The path of the configuration file to load.
Returns

(LuaConfig). A LuaConfig object.

get_log

DEPRECATED: This version of the get_log function is deprecated in NiFi Ingest 11.4.0 and later.

This version of the function is still available for existing implementations, but it might be incompatible with new functionality. This version of the function might be removed in future.

OpenText recommends that you use the function get_log( log_type ) instead.

The get_log function reads a configuration file and returns a LuaLog object that provides the capability to use the specified log stream.

Syntax
get_log( config, logstream )
Arguments
Argument Description
config (LuaConfig) A LuaConfig object that represents the configuration file which contains the log stream. You can obtain a LuaConfig object using the function get_config.
logstream (string) The name of the section in the configuration file that contains the settings for the log stream.
Returns

(LuaLog). A LuaLog object that provides the capability to use the log stream.

Example
local config = get_config("connector.cfg")
local log = get_log(config, "SynchronizeLogStream")

get_log

The get_log method returns a LuaLog object that provides the capability to write messages to a specified log type.

Syntax
get_log( [log_type] )
Arguments
Argument Description
log_type (string) The log type name.
Returns

(LuaLog). A LuaLog object.

Example

To write a log message from the ExecuteDocumentLua processor in NiFi:

local log = get_log()
log:write_line(log_level_normal(), "doing something...")

-- or use the following functions
log_info("My information message")
log_warn("My warning message")
log_error("My error message")

To write a log message to an ACI Server application log:

local log = get_log("application")
log:write_line(log_level_normal(), "doing something...")

get_log_service

The get_log_service function obtains a LuaLogService object, from which you can obtain a LuaLog object that you can use to write messages to a log file.

IMPORTANT: To obtain a LuaLog object for writing to a standard log stream, call the function without any arguments or use the function get_log instead. Set the config argument only when you want to write to a custom log file that is not controlled by the ACI Server.

Syntax
get_log_service( [config] )
Arguments
Argument Description
config (LuaConfig) A LuaConfig object that represents the configuration file which contains the logging settings. You can obtain a LuaConfig object using the function get_config.
Returns

(LuaLogService). A LuaLogService object.

Example

The following example shows how to use the get_log_service function to obtain a LuaLogService object. From this you can obtain a LuaLog object. The LuaLog object has a method, write_line, that writes messages to the log file.

local logService = get_log_service()
-- import is a standard log stream for CFS
local log = logService:get_log("import")
log:write_line( log_level_error() , "The log message")

The get_log function provides an easier way to accomplish the same task:

local log = get_log("import")
-- import is a standard log stream for CFS
log:write_line( log_level_error() , "The log message")

The following example demonstrates how to write messages to a custom log file. Declare the log service globally to avoid a LuaLogService object being created every time the script runs. For example, if you are writing a Lua script to use with a connector or CFS, call the get_log_service function outside the handler function.

local luaConfigString = [===[
[Logging]
LogLevel=FULL
0=LuaLogStream

[LuaLogStream]
LogTypeCSVs=lua
LogFile=lua.log
]===]
    
local config = LuaConfig:new(luaConfigString)

-- global log service instance for Lua log stream
luaLogService = get_log_service(config)

local luaLog = luaLogService:get_log("lua")
luaLog:write_line(log_level_normal(), "running Lua script")

getcwd

The getcwd function returns the current working directory of the application.

Syntax
getcwd()
Returns

(String). Returns a string containing the absolute path of the current working directory.

gobble_whitespace

Reduces multiple adjacent white spaces (tabs, carriage returns, spaces, and so on) in the specified string to a single space.

Syntax
gobble_whitespace( input )
Arguments
Argument Description
input (string) An input string.
Returns

(String). A string without adjacent white spaces.

hash_file

Hashes the contents of the specified file using the SHA1 or MD5 algorithm.

Syntax
hash_file( FileName, Algorithm )
Arguments
Argument Description
FileName (string) The name of the file.
Algorithm (string) The type of algorithm to use. Must be either SHA1 or MD5.
Returns

(String). A hash of the file contents.

hash_string

Hashes the specified string using the SHA1 or MD5 algorithm.

Syntax
hash_string( StringToHash, Algorithm )
Arguments
Argument Description
StringToHash (string) The string to hash.
Algorithm (string) The algorithm to use. Must be either SHA1 or MD5.
Returns

(String). The hashed input string.

is_dir

Checks if the supplied path is a directory.

Syntax
is_dir( path )
Arguments
Argument Description
path (string) The path to check.
Returns

(Boolean). Returns true if the supplied path is a directory, false otherwise.

log

The log function appends log messages to the specified file.

Syntax
log( file, message )
Arguments
Argument Description
file (string) The file to append log messages to.
message (string) The message to print to the file.

lower_case_utf8

Converts a UTF-8 string to lower case.

Syntax
lower_case_utf8( input )
Arguments
Argument Description
input (string) The input string.
Returns

(String). The original string in lower case.

move_file

Moves a file.

Syntax
move_file( src, dest [, overwrite] )
Arguments
Argument Description
src (string) The source file.
dest (string) The destination file.
overwrite (boolean) A boolean that specifies whether to move the file if the destination file already exists. If this argument is false, and the destination file already exists, the move operation fails. The default is true, which means that the destination file is overwritten.
Returns

(Boolean). Returns true to indicate success, false otherwise.

parse_csv

Parses a string of comma-separated values into individual strings. The method understands quoted values (such that parsing 'foot, "leg, torso", elbow' produces three values) and ignores white space around delimiters.

Syntax
parse_csv( input [, delimiter ] )
Arguments
Argument Description
input (string) The string to parse.
delimiter (string) The delimiter to use (the default delimiter is ",").
Returns

(Strings). You can put them in a table like this:

local results = { parse_csv("cat,tree,house", ",") };

parse_document_csv

Parses a CSV file into documents and calls a function on each document.

This function can handle CSV files with or without a header row, but if a header row is not present you must:

  • set the named parameter use_header_row to false.
  • specify the document field names to use by setting the named parameter csv_field_names.
Syntax
parse_document_csv( filename, handler [, params ] )
Arguments
Argument Description
filename (string) The path and file name of the CSV file to parse into documents.
handler (document_handler_function) The function to call on each document that is parsed from the CSV file.
params (table) A table of named parameters to configure parsing. The table maps parameter names (String) to parameter values. For information about the parameters that you can set, see the following table.
Named Parameters
Named Parameter Description
content_field (string, default DRECONTENT) The name of the field, in the CSV file, to use as the document content.
csv_field_names (string list) A list of names for the fields that exist in the CSV file. This overrides any header row, if one is present.
reference_field (string, default DREREFERENCE) The name of the field, in the CSV file, to use as the document reference.
use_header_row (boolean, default TRUE) Specify whether the CSV file includes a header row (whether the first row is a list of field names and not values). If this parameter is True and you do not set csv_field_names, the field names in the header row are used as the names of the document fields.
Example

The following example parses a CSV file named data.csv, and calls the function documentHandler on each document. The values in the field item_id become document references and the values in the field body become document content.

function documentHandler(document)
  -- do something, for example
  print(document:getReference())
end

...

parse_document_csv("./data.csv", documentHandler, {
        reference_field="item_id",
        content_field="body"
    })

The following example shows how to provide field names when there is no header row in the CSV file:

parse_document_csv("./data_no_header.csv", documentHandler, {
        use_header_row=false,
        csv_field_names={"DREREFERENCE", "title", "modified", "DRECONTENT"}
    })
Returns

Nil.

parse_document_idx

Parses an IDX file into documents and calls a function on each document.

Syntax
parse_document_idx( filename, handler )
Arguments
Argument Description
filename (string) The path of the IDX file to parse into documents.
handler (document_handler_function) The function to call on each document that is parsed from the IDX file. The function must accept a LuaDocument as the only argument.
Example

The following example uses the parse_document_idx function to parse an IDX file, and calls the function appendDocumentReference on each document.

local references = {}

function appendDocumentReference(document)
    table.insert(references, document:getReference())
end 

function read_idx_references(filename)
    parse_document_idx(filename, appendDocumentReference)
    return references
end
Returns

Nothing.

parse_document_idx

Parses an IDX file, or a string of IDX data, and returns a LuaDocument.

TIP: You can use this function if the file or string contains a single document. If you have a file or string that contains multiple documents, use one of the following functions instead:

  • parse_document_idx(filename, handler)
  • parse_document_idx(input, isFile, handler)
Syntax
parse_document_idx( input [, file] )
Arguments
Argument Description
input (string) The path to the IDX file, or a string of IDX data.
file (boolean, default false) Specifies whether the input is a file path.
Example

If you have a string named myIdxString that contains a document in IDX format, you can obtain a LuaDocument object as follows:

local myDocument = parse_document_idx(myIdxString)

Returns

(LuaDocument). A LuaDocument object that represents the document.

parse_document_idx

Parses an IDX file, or a string of IDX data, into documents and calls a function on each document.

Syntax
parse_document_idx( input, isFile, handler )
Arguments
Argument Description
input (string) The path to the IDX file, or a string of IDX data.
isFile (boolean) Specifies whether the input is a file path.
handler (document_handler_function) The function to call on each document that is parsed from the IDX file. The function must accept a LuaDocument as the only argument.
Returns

Nothing.

parse_document_xml

Parses an XML file into documents and calls a function on each document.

Syntax
parse_document_xml( filename, handler [, params ] )
Arguments
Argument Description
filename (string) The path of the XML file to parse into documents.
handler (document_handler_function) The function to call on each document that is parsed from the XML file. The function must accept a LuaDocument as the only argument.
params (table) A table of named parameters to configure parsing. The table maps parameter names (String) to parameter values. For information about the parameters that you can set, see the following table.
Named Parameters
Named Parameter Description
content_paths (string list, default DRECONTENT) The paths in the XML to the elements that contain document content. You can specify a list of paths.
document_root_paths (string list, default DOCUMENT) The paths in the XML to the elements that represent the root of a document. You can specify a list of paths.
include_root_path (boolean, default false) Specifies whether to include the document_root_paths node in the document metadata. The default value includes only children of the root node.
reference_paths (string list, default DREREFERENCE) The paths in the XML to elements that contain document references. Though you can specify a list of paths, there must be exactly one reference per document.
Example

The following example parses an XML file named data.xml, and calls the function printReference on each document. Two values have been set for the named parameter content_paths. You might want to do this if there are multiple fields that contain content or you want to use the same script with XML files that have different schema.

local function printReference(document)
    print(document:getReference())
end

local xmlParams = {
        document_root_paths={"DOC"},
        reference_paths={"REF"},
        content_paths={"CONTENT","MORE_CONTENT"}
    }

parse_document_xml("./data.xml", printReference, xmlParams)
Returns

Nothing.

parse_document_xml

Parses an XML file, or a string of XML data, and returns a LuaDocument.

TIP: You can use this function if the file or string contains a single document. If you have a file or string that contains multiple documents, use one of the following functions instead:

  • parse_document_xml(filename, handler [, params] )
  • parse_document_xml(input, isFile, handler [, params] )
Syntax
parse_document_xml( input [, file [, params ]] )
Arguments
Argument Description
input (string) The path to the XML file, or a string of XML data.
file (boolean, default false) Specifies whether the input is a file path.
params (table) A table of named parameters to configure parsing. The table maps parameter names (String) to parameter values. For information about the parameters that you can set, see the following table.
Named Parameters
Named Parameter Description
content_paths (string list, default DRECONTENT) The paths in the XML to the elements that contain document content. You can specify a list of paths.
document_root_paths (string list, default DOCUMENT) The paths in the XML to the elements that represent the root of a document. You can specify a list of paths.
include_root_path (boolean, default false) Specifies whether to include the document_root_paths node in the document metadata. The default value includes only children of the root node.
reference_paths (string list, default DREREFERENCE) The paths in the XML to elements that contain document references. Though you can specify a list of paths, there must be exactly one reference per document.
Example

If you have a string named myXmlString that contains a document in XML format, you can obtain a LuaDocument object as follows:

local xmlParams = {
        document_root_paths={"DOC"},
        reference_paths={"REF"},
        content_paths={"CONTENT","MORE_CONTENT"}
    }

local myDocument = parse_document_xml(myXmlString, false, xmlParams)
Returns

(LuaDocument). A LuaDocument object that represents the document.

parse_document_xml

Parses an XML file, or a string of XML data, into documents and calls a function on each document.

Syntax
parse_document_xml( input, isFile, handler [, params ] )
Arguments
Argument Description
input (string) The path to the XML file, or a string of XML data.
isFile (boolean) Specifies whether the input is a file path.
handler (document_handler_function) The function to call on each document that is parsed from the XML file. The function must accept a LuaDocument as the only argument.
params (table) A table of named parameters to configure parsing. The table maps parameter names (String) to parameter values. For information about the parameters that you can set, see the following table.
Named Parameters
Named Parameter Description
content_paths (string list, default DRECONTENT) The paths in the XML to the elements that contain document content. You can specify a list of paths.
document_root_paths (string list, default DOCUMENT) The paths in the XML to the elements that represent the root of a document. You can specify a list of paths.
include_root_path (boolean, default false) Specifies whether to include the document_root_paths node in the document metadata. The default value includes only children of the root node.
reference_paths (string list, default DREREFERENCE) The paths in the XML to elements that contain document references. Though you can specify a list of paths, there must be exactly one reference per document.
Returns

Nothing.

parse_json

Parses a string of JSON and returns a JSON value.

Syntax
parse_json( json )
Arguments
Argument Description
json (string) The input string to parse.
Returns

(LuaJsonValue). A LuaJsonValue containing the JSON data.

Example
local fh = io.open("example_json.json", "r")
local file_content = fh:read("*all")
fh:close()

local myJsonValue = parse_json(file_content)

if myJsonValue:is_object() then
  document:insertJson( myJsonValue:object() , "MyJsonField" )
elseif myJsonValue:is_array() then
  document:insertJson( myJsonValue:array() , "MyJsonField" )
end

If the file example_json.json contained the following JSON object:

{
  "product": "IDOL",
  "component": "CFS",
  "version": { "major": 11, "minor": 3 },
  "ports": [
    { "type": "ACI", "number": 7000 },
    { "type": "Service", "number": 17000 }
  ]
}

The resulting document might look like this:

<document>
   <reference>ref1</reference>
   <xmlmetadata>
      <MyJsonField>
        <component>CFS</component>
        <ports>
          <number>7000</number>
          <type>ACI</type>
        </ports>
        <ports>
          <number>17000</number>
          <type>Service</type>
        </ports>
        <product>IDOL</product>
        <version>
          <major>11</major>
          <minor>3</minor>
        </version>
      </MyJsonField>
   </xmlmetadata>
</document>
See Also

If you know that the input data is a JSON object, you can also use the function parse_json_object. If you know that the input data is a JSON array, you can also use the function parse_json_array.

parse_json_array

The parse_json_array function parses a string and returns a JSON array.

Syntax
parse_json_array( json )
Arguments
Argument Description
json (string) The input string to parse.
Returns

(LuaJsonArray). A LuaJsonArray containing the JSON data.

See Also

If you can't be sure whether the input data is a JSON array, you can use the function parse_json to parse the JSON. The parse_json function returns a LuaJsonValue, which can represent a JSON array or a JSON object.

parse_json_object

The parse_json_object function parses a string and returns a JSON object.

Syntax
parse_json_object( json )
Arguments
Argument Description
json (string) The input string to parse.
Returns

(LuaJsonObject). A LuaJsonObject containing the JSON data.

See Also

If you can't be sure whether the input data is a JSON object, you can use the function parse_json to parse the JSON. The parse_json function returns a LuaJsonValue, which can represent a JSON array or a JSON object.

parse_xml

Parses an XML string to a LuaXmlDocument.

NOTE: The following character encodings are supported. If the XML uses a different character encoding, you can use the function convert_encoding to convert the encoding before parsing the XML.

  • UTF-8
  • UTF-16
  • ISO-Latin-1 (ISO-8859-1)
  • ASCII
Syntax
parse_xml( xml )
Arguments
Argument Description
xml (string) XML data as a string.
Returns

(LuaXmlDocument). A LuaXmlDocument containing the parsed data, or nil if the string could not be parsed.

password_strength

Evaluates the strength of a password.

Syntax
password_strength( password )
Arguments
Argument Description
password (string) The password to test.
Returns

(Integer). A number (1-10) that represents the strength of the password (less than 2 is weak, 2-4 is acceptable, 5 or more is strong).

regex_match

Tests whether an input string matches a regular expression. The full string must match the regular expression, otherwise the function returns nil. To find matches within a string, OpenText recommends using the function regex_search.

Syntax
regex_match( input, regex [, case] )
Arguments
Argument Description
input (string) The input string.
regex (string) The regular expression to match against.
case (boolean) A boolean that specifies whether the match is case-sensitive. The match is case sensitive by default (true).
Returns

One or more strings, or nil.

If the string matches the regular expression, and the regular expression has no sub-matches, the full string is returned.

If the string matches the regular expression, and the regular expression has sub-matches, then only the sub-matches are returned.

If the string does not match the regular expression, there are no return values (any results are nil).

You can assign multiple strings to a table. To assign the return values to a table, surround the function call with braces. For example:

matches = { regex_match( input, regex ) }
Examples
local r1, r2, r3 = regex_match( "abracadabra", "(a.r)((?:a.)*ra)" )

Results: r1="abr", r2="acadabra", r3=nil

local r1, r2, r3 = regex_match( "abracadabra", "a.r(?:a.)*ra" )

Results: r1="abracadabra", r2=nil, r3=nil

regex_replace_all

Searches a string for matches to a regular expression, and replaces the matches according to the value specified by the replacement argument.

Syntax
regex_replace_all( input, regex, replacement )
Arguments
Argument Description
input (string) The string in which you want to replace values.
regex (string) The regular expression to use to find values to be replaced.
replacement (string) A string that specifies how to replace the matches of the regular expression.
Returns

(String). The modified string.

Examples
regex_replace_all("ABC ABC ABC", "AB", "A")
-- returns "AC AC AC"

regex_replace_all("One Two Three", "\\w{3}", "_")
-- returns "_ _ _ee"

regex_replace_all("One Two Three", "(\\w+) (\\w+)", "\\2 \\1")
-- returns "Two One Three"

regex_search

Performs a regular expression search on a string. This function returns a LuaRegexMatch object, rather than strings.

Syntax
regex_search ( input, regex [, case])
Arguments
Argument Description
input (string) The string in which to search.
regex (string) The regular expression with which to search.
case (boolean) Specifies whether matching is case-sensitive (default true).
Returns

(LuaRegexMatch).

script_path

The script_path function returns the path and file name of the script that is running.

Syntax
script_path()
Returns

(String, String) Returns the path of the folder that contains the script and the file name of the script, as separate strings.

Example
local script_directory, script_filename = script_path()

You can use this function to load scripts using their location relative to the current script. In the following example only the first return value from script_path() - the directory - is concatenated with "more_scripts/another_script.lua".

dofile(script_path().."more_scripts/another_script.lua")

send_aci_action

Sends a query to an ACI server. This method takes the action parameters as a table instead of the full action as a string, as with send_aci_command. This avoids issues with parameter values containing an ampersand (&).

Syntax
send_aci_action( host, port, action [, parameters] [, timeout] [, retries] [, sslParameters] )
Arguments
Argument Description
host (string) The ACI host to send the query to.
port (number) The port to send the query to.
action (string) The action to perform (for example, query).
parameters (table) A Lua table containing the action parameters, for example, { param1="value1", param2="value2" }
timeout (number) The number of milliseconds to wait before timing out. The default is 3000.
retries (number) The number of times to retry if the request fails. The default is 3.
sslParameters (table) A Lua table containing the SSL settings.
Returns

(String). Returns the XML response as a string. If required, you can call parse_xml on the string to return a LuaXmlDocument. If the request fails, it returns nil.

Example
send_aci_action( "localhost", 9000, "query" ,
			{text = "*", print = "all"} );
See Also

send_aci_command

Sends a query to an ACI server.

Syntax
send_aci_command( host, port, query [, timeout] [, retries] [, sslParameters] )
Arguments
Argument Description
host (string) The ACI host to send the query to.
port (number) The port to send the query to.
query (string) The query to send (for example, action=getstatus)
timeout (number) The number of milliseconds to wait before timing out. The default is 3000.
retries (number) The number of times to retry if the request fails. The default is 3.
sslParameters (table) A Lua table containing the SSL settings.
Returns

(String). Returns the XML response as a string. If required, you can call parse_xml on the string to return a LuaXmlDocument. If the request fails, it returns nil.

See Also

send_and_wait_for_async_aci_action

Sends a query to an ACI server and does not return until the action has completed.

You might use this method when you want to use an asynchronous action. The send_aci_action method returns as soon as it receives a response, which for an asynchronous action means that it returns a token. The method send_and_wait_for_async_aci_action sends an action and then waits. It polls the server until the action is complete and then returns the response.

Argument Description
host (string) The ACI host to send the query to.
port (number) The ACI port to send the query to.
action (string) The name of the action to perform.
parameters (table) A Lua table containing the action parameters, for example, { param1="value1", param2="value2" }
timeout (number) The number of milliseconds to wait before timing out. The default is 60000 (1 minute).
retries (number) The number of times to retry if the connection fails. The default is 3.
sslParameters (table) A Lua table containing the SSL settings.
Returns

(String). Returns the XML response as a string. If required, you can call parse_xml on the string to return a LuaXmlDocument. If the request fails, it returns nil.

See Also

send_http_request

The send_http_request function sends an HTTP request.

Syntax
send_http_request( params )
Arguments
Argument Description
params (table) Named parameters that configure the HTTP request. The table maps parameter names (string) to parameter values. For information about the parameters that you can set, see the following table.
Named Parameters
Named Parameter Description
url (string) The full URL for the HTTP request. If you provide a URL, the other parameters used to build the URL are not used.
method (string) The HTTP method to use (GET, POST, or DELETE). The default is "GET".
headers (table) A table of HTTP headers to send with the request. The table must map header names to values.
content (string) For HTTP POST, the data to be sent with the post.
site (string) The site to which the HTTP request is sent.
port (integer) The port to which the HTTP request is sent. By default, the request is sent to port 80.
uri (string) The URI to request.
params (table) Additional parameters for the request. The table must map parameter names to parameter values.
section (string) The name of a section in the configuration file that contains transport related parameters such as SSL or proxy settings. For a list of the HTTP Client configuration parameters that you can set in the configuration file, see HTTP Client Parameters.
options (table) A table of HTTP client options, and values, to use for the request. For a list of the HTTP Client options that you can set in the table, see HTTP Client Parameters.
Returns

String. The HTTP response.

The send_http_request function can throw an exception if the request fails. You can catch an exception by calling send_http_request using the Lua function pcall.

Examples

The following example shows how to make a simple request:

local wikipedia_page = send_http_request(
   {url = "http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"} )

The following example shows how to make the same request but catch any exceptions with the Lua pcall function:

local result, response = pcall ( send_http_request,
   {url = "http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"} )

When the send_http_request function is successful, the result variable is true and response contains the response. If an exception is thrown from send_http_request, the result variable is false and response contains the error message.

The following examples demonstrate how to add additional named parameters:

local google_search = send_http_request(
   {site = "www.google.co.uk", port = 80, uri = "/search",
   params = {q = "http protocol", safe = "active"}} )
local search = send_http_request(
   {site = "www.site.com", port = 80, uri = "/query",
   params = {text = "http headers", maxresults = "10"}
   headers = { Cache-Control = "no-cache" }} )

sleep

The sleep function pauses the thread.

Syntax
sleep( milliseconds )
Arguments
Argument Description
milliseconds (number) The number of milliseconds for which to pause the current thread.

unzip_file

Extracts the contents of a zip file.

Syntax
unzip_file( path, dest )
Arguments
Argument Description
path (string) The path and filename of the file to unzip.
dest (string) The destination path where files are extracted.
Returns

(Boolean). Returns a Boolean indicating success or failure.

upper_case_utf8

Converts a UTF-8 string to upper case.

Syntax
upper_case_utf8( input )
Arguments
Argument Description
input (string) The input string.
Returns

(String). The original string in upper case.

url_escape

Percent-encodes a string.

Syntax

url_escape( input )

Arguments
Argument Description
input (string) The string to percent-encode.
Returns

(String). The percent-encoded string.

url_unescape

The url_unescape function replaces URL escaped characters and returns a standard string.

Syntax

url_unescape( input )

Arguments
Argument Description
input (string) The string to process.
Returns

(String). The modified string.

xml_encode

Takes a string and encodes it using XML escaping.

Syntax
xml_encode ( content )
Arguments
Argument Description
content (string) The string to encode.
Returns

(String).

zip_file

The zip_file function zips the supplied path (file or directory). It overwrites the output file only if you set the optional overwrite argument to true.

Syntax
zip_file( path [, overwrite] )
Arguments
Argument Description
path (string) The path or filename of the file or folder to zip.
overwrite (boolean) A boolean that specifies whether to force the creation of the zip file if an output file already exists. The default is false.
Returns

(Boolean). Returns a Boolean indicating success or failure. On success writes a file called path.zip.

LuaConfig Methods

A LuaConfig object provides access to configuration information. You can retrieve a LuaConfig for a given configuration file using the get_config function.

If you have a LuaConfig object called config you can call its methods using the ':' operator. For example:

config:getValue(sectionName, parameterName)
Constructor Description
LuaConfig:new The constructor for a LuaConfig object (creates a new LuaConfig object).
Method Description
getEncryptedValue Returns the unencrypted value from the config of an encrypted value.
getValue Returns the value of the configuration parameter key in a given section.
getValues Returns all the values of a configuration parameter if you have multiple values for a key (for example, a comma-separated list or numbered list like keyN).

getEncryptedValue

The getEncryptedValue method returns the unencrypted value from the configuration file of an encrypted value.

Syntax
getEncryptedValue( section, parameter )
Arguments
Argument Description
section (string) The section in the configuration file.
parameter (string) The parameter in the configuration file to get the value for.
Returns

(String). The unencrypted value.

getValue

The getValue method returns the value of the configuration parameter key in a given section. If the key does not exist in the section, then it returns the default value.

Syntax
getValue( section, key [, default] )
Arguments
Argument Description
section (string) The section name in the configuration file.
key (string) The name of the key from which to read.
default (string/boolean/number) The default value to use if no key is found.
Returns

A string, boolean, or integer containing the value read from the configuration file.

getValues

The getValues method returns multiple values for a parameter (for example, a comma-separated list or numbered list like keyN).

Syntax
getValues( section, parameter )
Arguments
Argument Description
section (string) The section in the configuration file.
parameter (string) The parameter to find in the configuration file.
Returns

(Strings). The strings can be assigned to a table. To map the return values to a table, surround the function call with braces. For example:

values = { config:getValues( section, parameter ) }

LuaConfig:new

The constructor for a LuaConfig object (creates a new LuaConfig object).

Syntax
LuaConfig:new( config_buffer )
Arguments
Argument Description
config_buffer (string) The configuration to use to create the LuaConfig object.
Returns

(LuaConfig). The new LuaConfig object.

Example
local config_buffer = "[default]\nparameter=value"
local config = LuaConfig:new(config_buffer)

LuaDocument Methods

This section describes the methods provided by the LuaDocument object. A LuaDocument allows you to access and modify the reference, metadata and content of a document.

If you have a LuaDocument object called document you can call its methods using the ':' operator. For example:

document:addField(name, value)
Constructor Description
LuaDocument:new The constructor for a LuaDocument object (creates a new LuaDocument object that only contains a reference).
Method Description
addField Creates a new field.
addSection Add an empty section to the end of the document.
appendContent Appends content to the existing content of the document.
copyField Creates a new named field with the same value as an existing named field.
copyFieldNoOverwrite Copies a field to a certain name but does not overwrite the existing value.
countField Returns the number of fields with the name specified.
deleteField Deletes a field from the document.
deleteFieldByPath Deletes all document fields with the specified path.
getContent Returns the document content.
getField Returns the first field with a specified name.
getFieldNames Returns all the field names for the document.
getFields Returns all fields with the specified name.
getFieldsByRegex Returns all fields where the field name or path matches a regular expression.
getFieldValue Gets a field value.
getFieldValues Gets all values of a multi-valued field.
getNextSection Gets the next section in a document, allowing you to perform find or add operations on every section.
getReference Returns the document reference.
getSection Returns a LuaDocument object with the specified section as the active section.
getSectionCount Returns the number of sections in the document.
getValueByPath Gets the value of the document field or sub field with the specified path.
getValuesByPath Gets all values of a multi-value document field or sub field, with the specified path.
hasField Checks whether the document has a named field.
insertJson Inserts metadata, from a JSON string, into a document.
insertXml Inserts XML metadata into a document.
insertXmlWithoutRoot Inserts XML metadata into a document.
removeSection Removes a section from a document.
renameField Renames a field.
setContent Sets the content for a document.
setFieldValue Sets a field value.
setReference Sets the document reference.
to_idx Returns a string containing the document in IDX format.
to_json Returns a string containing the document in JSON format.
to_xml Returns a string containing the document in XML format.
writeStubIdx Writes out a stub IDX document.
writeStubXml Writes out a stub XML document.

addField

The addField method adds a new field to the document.

Syntax
addField ( fieldname, fieldvalue )
Arguments
Argument Description
fieldname (string) The name of the field to add.
fieldvalue (string) The value to set for the field.
Returns

(LuaField) A LuaField object representing the new field.

addSection

The addSection method adds an empty section to the end of the document.

Syntax
addSection()
Returns

(LuaDocument). Returns a LuaDocument object representing the document, with the new section as the active section.

Example
local newSection = document:addSection()   -- Add a new section to the document
newSection:setContent("content")           -- Set content for the new section

appendContent

The appendContent method appends content to the existing content (the DRECONTENT field) of a document or document section.

Syntax
appendContent ( content [, number])
Arguments
Argument Description
content (string) The content to append.
number (number) The document section to modify. If you do not specify this argument, content is appended to the last section. If you specify a number greater than the number of existing sections, additional empty sections are created.
Examples
-- Append content to the last section
document:appendContent("content")

-- Append content to section 7, empty sections are created before this section if necessary  
document:appendContent("content", 7)

copyField

The copyField method copies a field value to a new field. If the target field already exists it is overwritten.

Syntax
copyField ( sourcename, targetname [, case] )
Arguments
Argument Description
sourcename (string) The name of the field to copy.
targetname (string) The destination field name.
case (boolean) A boolean that specifies whether sourcename is case-sensitive. The field name is case sensitive by default (true).

copyFieldNoOverwrite

The copyFieldNoOverwrite method copies a field value to a new field but does not overwrite the existing value. After calling this function the target field will contain all values of the source field in addition to any values it already had.

Syntax
copyFieldNoOverwrite( sourcename, targetname [, case])
Arguments
Argument Description
sourcename (string) The name of the field to copy.
targetname (string) The destination field name.
case (boolean) A boolean that specifies whether sourcename is case-sensitive. The name is case sensitive by default (true).

countField

The countField method returns the number of fields with the specified name.

Syntax
countField( fieldname [, case] )
Arguments
Argument Description
fieldname (string) The name of the field to count.
case (boolean) A boolean that specifies whether fieldname is case sensitive. The field name is case sensitive by default (true).
Returns

(Number) The number of fields with the specified name.

deleteField

The deleteField method deletes a field from a document. If you specify the optional value argument, the field is deleted only if has the specified value.

Syntax
deleteField( fieldName [, case] )
deleteField( fieldName, value [, case] )
Arguments
Argument Description
fieldname (string) The name of the field to delete.
value (string) The value of the field. If this is specified only fields with matching names and values are deleted. If this is not specified, all fields that match fieldname are deleted.
case (boolean) A boolean that specifies whether fieldname is case sensitive. The field name is case sensitive by default (true).

deleteFieldByPath

The deleteFieldByPath method removes all document fields with the specified path.

Syntax
deleteFieldByPath( path )
Arguments
Argument Description
path (string) The path of the field(s) to delete.
Example
document:deleteFieldByPath("my/metadata/subfield")

getContent

The getContent method gets the content (the value of the DRECONTENT field) for a document or document section.

Syntax
getContent([number])
Arguments
Argument Description
number (number) The document section for which you want to return the content. If you do not specify this argument, the method returns the content of the active section. For the document object passed to the script's handler function, the active section is the first section (section 0).
Returns

(String). The document content as a string.

Examples
local content7 = document:getContent(7)     -- Get content for section 7
local section = document:getSection(3)      -- Get document for section 3
local content3 = section:getContent()       -- Get content for section 3
local content0 = document:getContent()      -- Get content for section 0

getField

The getField method returns a LuaField object representing the field with the specified name.

Syntax
getField( name [, case])
Arguments
Argument Description
name (string) The name of the field.
case (boolean) A boolean that specifies whether the name argument is case-sensitive. The name is case sensitive by default (true).
Returns

(LuaField). A LuaField object.

getFieldNames

The getFieldNames method returns all of the field names for the document.

Syntax
getFieldNames()
Returns

(Strings) The names of the fields. To map the return values to a table, surround the function call with braces. For example:

names = { document:getFieldNames() }

getFields

The getFields method returns LuaField objects where each object represents a field that matches the specified name.

Syntax
getFields( name [, case])
Arguments
Argument Description
name (string) The name of the field.
case (boolean) A boolean that specifies whether the name argument is case-sensitive. The name is case sensitive by default (true).
Returns

(LuaFields) One LuaField for each matching field. To map the return values to a table, surround the function call with braces. For example:

fields = { document:getFields( name ) }

getFieldsByRegex

The getFieldsByRegex method returns all document fields where the field name or path matches a regular expression.

Syntax
getFieldsByRegex( regex [, recursive [, matchFullPath [, caseSensitive ]]])
Arguments
Argument Description
regex (string) The regular expression to match field names or paths against.
recursive (boolean, default true) Specifies whether to search recursively. If you set this argument to false, the method only returns fields at the root of the document.
matchFullPath (boolean, default true) Specifies whether to match against the full path of the field. If you set this argument to false, the regular expression has to match only the field name.
caseSensitive (boolean, default true) Specifies whether matching is case-sensitive.
Returns

(LuaFields) A list of LuaField objects where each LuaField represents a matching field. To map the returned fields to a table, surround the function call with braces as shown in the following example.

Example
local fields = { document:getFieldsByRegex("Prefix_.*", true, false, false) }
for i, field in ipairs(fields) do
    print field:value()
end

getFieldValue

The getFieldValue method gets the value of a field in a document. To return the values of a multi-value field, see getFieldValues.

Syntax
getFieldValue( fieldname [, case])
Arguments
Argument Description
fieldname (string) The name of the field to be retrieved.
case (boolean) A boolean that specifies whether fieldname is case-sensitive. The argument is case sensitive by default (true).
Returns

(String). A string containing the value.

getFieldValues

The getFieldValues method gets all values from all fields that have the same name.

Syntax
getFieldValues( fieldname [, case])
Arguments
Argument Description
fieldname (string) The name of the field.
case (boolean) A boolean that specifies whether fieldname is case-sensitive. The argument is case sensitive by default (true).
Returns

(Strings). Strings that contain the values. To map the return values to a table, surround the function call with braces. For example:

fieldvalues = { document:getFieldValues( fieldname ) }

getNextSection

The getNextSection method returns the next section of a document (if the document has been divided into sections).

The document object passed to the script's handler function represents the first section of the document. This means that the methods described in this section read and modify only the first section.

Calling getNextSection on the LuaDocument passed to the handler function will always return the second section. To perform operations on every section, see the example below.

When a document is divided into sections, each section has the same fields. The only difference between each section is the document content (the value of the DRECONTENT field).

Syntax
getNextSection()
Returns

(LuaDocument) A LuaDocument object that contains the next DRE section.

Example

To perform operations on every section, use the following script.

local section = document
while section do
	-- Manipulate section
	section = section:getNextSection()
end

getReference

The getReference method returns a string containing the reference (the value of the DREREFERENCE document field).

Syntax
getReference()
Returns

(String). A string containing the reference.

getSection

The getSection method returns a LuaDocument object with the specified section as the active section.

Syntax
getSection(number)
Arguments
Argument Description
number (number) The document section for which you want to return a LuaDocument object.
Returns

(LuaDocument). A LuaDocument object with the specified section as the active section.

Example
-- Get object for section 7 of document
local section = document:getSection(7)

-- Get the content from the section
local content = section:getContent()

getSectionCount

The getSectionCount method returns the number of sections in a document.

Syntax
getSectionCount()
Returns

(Number). The number of sections.

Example
local sectionCount = document:getSectionCount()

getValueByPath

The getValueByPath method gets the value of a document field. The field is specified by its path, which means that you can get the value of a sub field. If you pass this method the path of a multi-value field, only the first value is returned. To return all of the values from a multi-value field, see getValuesByPath.

Syntax
getValueByPath( path )
Arguments
Argument Description
path (string) The path of the field.
Returns

(String). A string containing the value.

Example
local value = document:getValueByPath("myfield")
local subfieldvalue = document:getValueByPath("myfield/subfield")

getValuesByPath

The getValuesByPath method gets all values of a document field. The field is specified by its path, which means that you can get values from a sub field.

Syntax
getValuesByPath( path )
Arguments
Argument Description
path (string) The path of the field.
Returns

(Strings). Strings that contain the values. To map the return values to a table, surround the function call with braces. For example:

fieldvalues = { document:getValuesByPath("myfield/subfield") }

hasField

The hasField method checks to see if a field exists in the current document.

Syntax
hasField ( fieldname [, case])
Arguments
Argument Description
fieldname (string) The name of the field.
case (boolean) A boolean that specifies whether the fieldname is case-sensitive. The field name is case-sensitive by default.
Returns

(Boolean). True if the field exists, false otherwise.

insertJson

The insertJson method inserts metadata from a JSON string, LuaJsonObject, or LuaJsonArray, into a document.

Syntax
insertJson ( json [, fieldName] )
Arguments
Argument Description
json (string or LuaJsonArray or LuaJsonObject) The JSON to insert into the document.
fieldName (string) The name of the metadata field to add the JSON to. This field is created if it does not exist. If you do not specify a field the JSON is added at the root of the document.
Example

The following example Lua script uses the insertJson method to add metadata to a document:

function handler(document)
  local jsonString = [[
    {"email":"[email protected]",
     "name":"A N Example",
     "address":
       {"address1":"New street",
        "city":"Cambridge",
        "country":"Great Britain"},
     "id":15}
  ]]

  document:insertJson( jsonString , "MyField")
  return true
end

When written to an IDX file, the resulting document looks like this:

#DREREFERENCE c:\test.html
#DREFIELD DREFILENAME="c:\test.html"
...
#DREFIELD MyField/address/address1="New street"
#DREFIELD MyField/address/city="Cambridge"
#DREFIELD MyField/address/country="Great Britain"
#DREFIELD MyField/email="[email protected]"
#DREFIELD MyField/id="15"
#DREFIELD MyField/name="A N Example"
#DRECONTENT
Some content

#DREENDDOC

insertXml

The insertXml method inserts XML metadata into the document.

Syntax
insertXml ( node )
Arguments
Argument Description
node (LuaXmlNode) The node to insert.
Returns

(LuaField). A LuaField object of the inserted data.

insertXmlWithoutRoot

The insertXmlWithoutRoot method inserts XML metadata into the document.

This method does not insert the top level node. All of the child nodes are inserted into the document. insertXmlWithoutRoot(node) is therefore equivalent to calling insertXml() for each child node.

Syntax
insertXmlWithoutRoot ( node )
Arguments
Argument Description
node (LuaXmlNode) The node to insert.

LuaDocument:new

The constructor for a LuaDocument object (creates a new LuaDocument object that only contains a reference).

Syntax
LuaDocument:new( reference )
Arguments
Argument Description
reference (string) The reference to assign to the new document.
Returns

(LuaDocument). The new LuaDocument object.

Example
local reference = "my_reference"
local document = LuaDocument:new(reference)

removeSection

The removeSection method removes a section from a document.

Syntax
removeSection( sectionNumber )
Arguments
Argument Description
sectionNumber (number) A zero-based index that specifies the section to remove. For example, to remove the second section, set this argument to 1.
Returns

Nothing.

Example
-- Example that removes the last section of a document
if document:getSectionCount() > 0 then
   local lastSection = document:getSectionCount() - 1
   document:removeSection( lastSection )  
end

renameField

The renameField method changes the name of a field.

Syntax
renameField( currentname, newname [, case])
Arguments
Argument Description
currentname (string) The name of the field to rename.
newname (string) The new name of the field.
case (boolean) A boolean that specifies whether the currentname argument is case-sensitive. The argument is case sensitive by default (true).

setContent

The setContent method sets the content (the value of the DRECONTENT field) for a document or document section.

Syntax
setContent( content [, number] )
Arguments
Argument Description
content (string) The content to set for the document or document section.
number (number) The document section to modify. If you do not specify a number, the method modifies the active section. For the document object passed to the script's handler function, the active section is the first section (section 0). If you specify a number greater than the number of existing sections, additional empty sections are created.
Examples
-- Set content for section 0
document:setContent("content0")

-- Get document for section 1
local section = document:getNextSection()

-- Set content for section 1
section:setContent("content1")

-- Set content for section 7, and assign sections 2-6 to
-- empty string if non-existent   
document:setContent("content7", 7)

setFieldValue

The setFieldValue method sets the value of a field in a document. If the field does not exist, it is created. If the field already exists, the existing value is overwritten.

Syntax
setFieldValue( fieldname, newvalue )
Arguments
Argument Description
fieldname (string) The name of the field to set.
newvalue (string) The value to set for the field.

setReference

The setReference method sets the reference (the value of the DREREFERENCE document field) to the string passed in.

Syntax
setReference( reference )
Arguments
Argument Description
reference (string) The reference to set.

to_idx

The to_idx method returns a string containing the document in IDX format.

Syntax
to_idx()
Returns

(String). Returns the document as a string.

to_json

The to_json method returns a string containing the document in JSON format.

Syntax
to_json()
Returns

(String). Returns the document as a string.

to_xml

The to_xml method returns a string containing the document in XML format.

Syntax
to_xml()
Returns

(String). Returns the document as a string.

writeStubIdx

The writeStubIdx method writes out a stub IDX document (a metadata file used by Knowledge Discovery applications). The file is created in the current folder, but you can specify a full path and file name if you want to create the file in another folder.

Syntax
writeStubIdx( filename )
Arguments
Argument Description
filename (string) The name of the file to create.
Returns

(Boolean). True if written, false otherwise.

writeStubXml

The writeStubXml method writes out an XML file containing the metadata for the document. The file is created in the current folder but you can specify a full path and file name if you want to create the file in another folder.

Syntax
writeStubXml( filename )
Arguments
Argument Description
filename (String) The name of the file to create.
Returns

(Boolean) True if successful, false otherwise.

LuaField Methods

This section describes the methods provided by LuaField objects. A LuaField represents a single field in a document. You can retrieve LuaField objects for a document using the LuaDocument getField and getFields methods. In its simplest form a field has just a name and a value, but it can also contain sub-fields.

If you have a LuaField object called field you can call its methods using the ':' operator. For example:

field:addField(name, value)
Method Description
addField Adds a sub field with the specified name and value.
copyField Copies the sub field to another sub field.
copyFieldNoOverwrite Copies the sub field to another sub field but does not overwrite the destination.
countField Returns the number of sub fields that exist with the specified name.
deleteAttribute Deletes the attribute with the specified name.
deleteField Deletes the sub field(s) with the specified name.
deleteFieldByPath Deletes the sub field(s) with the specified path.
getAttributeValue Gets the value of an attribute.
getField Gets the sub field specified by the name.
getFieldNames Returns the names of all sub fields of this field.
getFields Gets all the sub fields specified by the name.
getFieldsByRegex Gets all sub fields where the sub field name or path matches a regular expression.
getFieldValues Returns all the values of the sub field with the specified name.
getValueByPath Returns the value of a sub field with the specified path.
getValuesByPath Returns all the values of the sub field with the specified path.
hasAttribute Returns a Boolean specifying if the field has the specified attribute passed in by name.
hasField Returns a Boolean specifying if the sub field exists or not.
insertJson Inserts metadata from a JSON string, LuaJsonObject, or LuaJsonArray into the field.
insertXml Inserts XML metadata into a document.
insertXmlWithoutRoot Inserts XML metadata into a document.
name Returns the name of the field object in a string.
renameField Renames a sub field.
setAttributeValue Sets the value for the specified attribute of the field.
setValue Sets the value of the field.
value Returns the value of the field object.

addField

The addField method adds a sub field with the specified name and value.

Syntax
addField( fieldname, fieldvalue )
Arguments
Argument Description
fieldname (string) The name of the field.
fieldvalue (string) The value of the field.
Returns

(LuaField) A LuaField object representing the new field.

copyField

The copyField method copies a sub field to another sub field. If the target sub field exists it is overwritten.

Syntax
copyField ( from, to [, case])
Arguments
Argument Description
from (string) The name of the field to copy.
to (string) The name of the field to copy to.
case (boolean) A boolean that specifies whether the from argument is case sensitive. The argument is case sensitive by default (true).

copyFieldNoOverwrite

The copyFieldNoOverwrite method copies the sub field to another sub field but does not overwrite the destination. After this operation the destination field contains all the values of the source field as well as any values it already had.

Syntax
copyFieldNoOverwrite( from, to [, case])
Arguments
Argument Description
from (string) The name of the field to copy.
to (string) The name of the field to copy to.
case (boolean) A boolean that specifies whether the from argument is case sensitive. The argument is case sensitive by default (true).

countField

The countField method returns the number of sub fields that exist with the specified name.

Syntax
countField ( fieldname [, case])
Arguments
Argument Description
fieldname (string) The name of the field.
case (boolean) A boolean that specifies whether the fieldname argument is case sensitive. The argument is case sensitive by default (true).
Returns

(Number). The number of sub fields that exist with the specified name.

deleteAttribute

The deleteAttribute method deletes the specified field attribute.

Syntax
deleteAttribute( name )
Arguments
Argument Description
name (string) The name of the attribute to delete.

deleteField

The deleteField method deletes the sub field with the specified name.

Syntax
deleteField( name [, case] ) 
deleteField( name , value [, case] ) 
Arguments
Argument Description
name (string) The name of the sub field to delete.
value (string) The value of the sub field. If this is specified a field is deleted only if it has the specified name and value. If this is not specified, all fields with the specified name are deleted.
case (boolean) A boolean that specifies whether the name argument is case sensitive. The argument is case sensitive by default (true).

deleteFieldByPath

The deleteFieldByPath method removes the sub field(s) with the specified path.

Syntax
deleteFieldByPath( path )
Arguments
Argument Description
path (string) The path of the sub-field(s) to delete.
Example
myField:deleteFieldByPath("path/to/subfield")

getAttributeValue

The getAttributeValue method gets the value of the specified attribute.

Syntax
getAttributeValue( name )
Arguments
Argument Description
name (string) The name of the attribute.
Returns

(String). The attribute value.

getField

The getField method returns the specified sub field.

Syntax
getField ( name [, case])
Arguments
Argument Description
name (string) The name of the field to return.
case (boolean) A boolean that specifies whether the name argument is case sensitive. The argument is case sensitive by default (true).
Returns

(LuaField) A LuaField object.

getFieldNames

The getFieldNames method returns the names of the sub fields in the LuaField object.

Syntax
getFieldNames()
Returns

(Strings). The names of the sub fields. The strings can be assigned to a table. To map the return values to a table, surround the function call with braces. For example:

fieldnames = { field:getFieldNames() }

getFields

The getFields method returns all of the sub fields specified by the name argument.

Syntax
getFields( name [, case] )
Arguments
Argument Description
name (string) The name of the fields.
case (boolean) A boolean that specifies whether the name argument is case sensitive. The argument is case sensitive by default (true).
Returns

(LuaFields) One LuaField per matching field. The objects can be assigned to a table. To map the return values to a table, surround the function call with braces. For example:

fields = { field:getFields( name [, case]) }

getFieldsByRegex

The getFieldsByRegex method returns all sub fields where the sub field name or path (relative to this field) matches a regular expression.

Syntax
getFieldsByRegex( regex [, recursive [, matchFullPath [, caseSensitive ]]])
Arguments
Argument Description
regex (string) The regular expression to match field names or paths against.
recursive (boolean, default true) Specifies whether to search recursively. If you set this argument to false, the method only returns fields that are direct descendants of this field.
matchFullPath (boolean, default true) Specifies whether to match against the path of the sub field (relative to the field the method is called on). If you set this argument to false, the regular expression only has to match the field name.
caseSensitive (boolean, default true) Specifies whether matching is case-sensitive.
Returns

(LuaFields) A list of LuaField objects where each LuaField represents a matching field. To map the returned fields to a table, surround the function call with braces as shown in the following example.

Example
local fields = { myField:getFieldsByRegex("Prefix_.*", true, false, false) }
for i, field in ipairs(fields) do
    print field:value()
end

getFieldValues

The getFieldValues method returns the values of all of the sub fields with the specified name.

Syntax
getFieldValues( fieldname [, case] )
Arguments
Argument Description
fieldname (string) The name of the field.
case (boolean) A boolean that specifies whether the fieldname argument is case sensitive. The argument is case sensitive by default (true).
Returns

(Strings) One string for each value. The strings can be assigned to a table. To map the return values to a table, surround the function call with braces. For example:

fieldvalues = { field:getFieldValues( fieldname ) }

getValueByPath

The getValueByPath method gets the value of a sub-field, specified by path. If you pass this method the path of a sub-field that has multiple values, only the first value is returned. To return all of the values from a multi-value sub-field, see getValuesByPath.

Syntax
getValueByPath( path )
Arguments
Argument Description
path (string) The path of the sub-field.
Returns

(String). A string containing the value.

Example

Consider the following document:

<DOCUMENT>
  ...
  <A_FIELD>
    <subfield>
      <anothersubfield>the value to return</anothersubfield>
    </subfield>
  </A_FIELD>
  ...
</DOCUMENT>

The following example demonstrates how to retrieve the value "the value to return" from the sub-field anothersubfield, using a LuaField object representing A_FIELD:

local field = document:getField("A_FIELD")
local value = field:getValueByPath("subfield/anothersubfield")

getValuesByPath

The getValuesByPath method gets the values of a sub-field, specified by path.

Syntax
getValuesByPath( path )
Arguments
Argument Description
path (string) The path of the sub-field.
Returns

(Strings). Strings that contain the values. To map the return values to a table, surround the function call with braces. For example:

fieldvalues = { myfield:getValuesByPath("subfield/anothersubfield") }
Example

Consider the following document:

<DOCUMENT>
  ...
  <A_FIELD>
    <subfield>
      <anothersubfield>one</anothersubfield>
      <anothersubfield>two</anothersubfield>
      <anothersubfield>three</anothersubfield>
    </subfield>
  </A_FIELD>
  ...
</DOCUMENT>

The following example demonstrates how to retrieve the values "one", "two", and "three" from the sub-field anothersubfield, using a LuaField object representing A_FIELD:

local field = document:getField("A_FIELD")
local values = { field:getValuesByPath("subfield/anothersubfield") }

hasAttribute

The hasAttribute method returns a Boolean indicating whether the field has the specified attribute.

Syntax
hasAttribute( name )
Arguments
Argument Description
name (string) The name of the attribute.
Returns

(Boolean). A Boolean specifying if the field has the specified attribute.

hasField

The hasField method returns a Boolean specifying if the sub field exists.

Syntax
hasField( fieldname [, case])
Arguments
Argument Description
fieldname (string) The name of the field.
case (boolean) A boolean that specifies whether the fieldname argument is case sensitive. The argument is case sensitive by default (true).
Returns

(Boolean). A Boolean specifying if the sub field exists or not.

insertJson

The insertJson method inserts metadata from a JSON string, LuaJsonObject, or LuaJsonArray, into the field.

Syntax
insertJson ( json [, fieldName] )
Arguments
Argument Description
json (string or LuaJsonArray or LuaJsonObject) The JSON to insert into the field.
fieldName (string) The name of a sub-field to add the JSON to. If you set this argument, a sub-field is created. If you do not set this argument, the JSON is added to the field that the method was called on.
See Also

insertXml

The insertXml method inserts XML metadata into the document. When called on a LuaField, the insertXml method inserts the fields as children of the LuaField.

Syntax
insertXml ( node )
Arguments
Argument Description
node (LuaXmlNode) The node to insert.
Returns

(LuaField). A LuaField object of the inserted data.

insertXmlWithoutRoot

The insertXmlWithoutRoot method inserts XML metadata into the document.

This method does not insert the top level node. All of the child nodes are inserted into the document. insertXmlWithoutRoot(node) is therefore equivalent to calling insertXml() for each child node.

Syntax
insertXmlWithoutRoot ( node )
Arguments
Argument Description
node (LuaXmlNode) The node to insert.

name

The name method returns the name of the field object.

Syntax
name()
Returns

(String). The name of the field object.

renameField

The renameField method renames a sub field.

Syntax
renameField( oldname, newname [, case] )
Arguments
Argument Description
oldname (string) The previous name of the field.
newname (string) The new name of the field.
case (boolean) A boolean that specifies whether the oldname argument is case sensitive. The argument is case sensitive by default (true).

setAttributeValue

The setAttributeValue method sets the value for the specified attribute of the field.

Syntax
setAttributeValue( attribute, value )
Arguments
Argument Description
attribute (string) The name of the attribute to set.
value (string) The value to set.

setValue

The setValue method sets the value of the field.

Syntax
setValue( value )
Arguments
Argument Description
value (string) The value to set.

value

The value method returns the value of the field object.

Syntax
value()
Returns

(String). The value of the field object.

LuaHttpRequest Methods

This section describes the methods provided by LuaHttpRequest objects.

If you have a LuaHttpRequest object called request you can call its methods using the ':' operator. For example:

request:send()
Constructor Description
LuaHttpRequest:new The constructor for a LuaHttpRequest object (creates a new LuaHttpRequest).
Method Description
send Sends the HTTP request.
set_body Sets the body of the HTTP request.
set_config Specifies settings to use for sending the HTTP request.
set_header Adds a header to the HTTP request.
set_headers Replaces all headers in the HTTP request with new headers.
set_method Specifies the HTTP request method to use when sending the request, for example GET or POST.
set_url Sets the URL that you want to send the HTTP request to.

LuaHttpRequest:new

The constructor for a LuaHttpRequest object (creates a new LuaHttpRequest).

Syntax
LuaHttpRequest:new( config, section )
Arguments
Argument Description
config (LuaConfig) The LuaConfig object that contains the settings for sending the HTTP request. To obtain a LuaConfig object, see the function get_config or LuaConfig:new.
section (string) The name of the configuration section from which to read the settings.
Returns

(LuaHttpRequest). The new LuaHttpRequest object.

Example

The following example creates a new LuaHttpRequest object by reading configuration settings from a string that is defined in the script:

local config_string = [===[
[HTTP]
ProxyHost=proxy.domain.com
ProxyPort=8080
SSLMethod=NEGOTIATE
]===]

local config = LuaConfig:new(config_string)
local request = LuaHttpRequest:new(config, "HTTP")

send

The send method sends the HTTP request.

Syntax
send()
Returns

(LuaHttpResponse). A LuaHttpResponse object.

The send method can throw an exception if the request fails. You can catch an exception by calling the method using the Lua function pcall.

Example

The following example shows how to send a request:

local config_string = [===[
[HTTP]
ProxyHost=proxy
ProxyPort=8080
SSLMethod=NEGOTIATE
]===]

local config = LuaConfig:new(config_string)
local request = LuaHttpRequest:new(config, "HTTP")
request:set_url("https://www.example.com")
request:set_method("GET")

local result, response = pcall(LuaHttpRequest.send, request)

if (result) then
    print ("Success: " , response:get_http_code())
else
    print ("Error: " , response)
end

When the send method is successful, the result variable is true and response is a LuaHttpResponse object. If an exception is thrown from the send method, the result variable is false and response contains the error message.

set_body

The set_body method sets the body of the HTTP request.

Syntax
set_body( body )
Arguments
Argument Description
body (string or nil) The body of the HTTP request.

set_config

The set_config method specifies settings to use for sending the HTTP request (in the form of a section from a configuration file). For example, you can specify the proxy server to use by setting the parameters ProxyHost and ProxyPort, or specify the SSL version to use by setting SSLMethod.

Syntax
set_config( config, section )
Arguments
Argument Description
config (LuaConfig) The LuaConfig object that contains the settings for sending the HTTP request. To obtain a LuaConfig object, see the function get_config or LuaConfig:new.
section (string) The name of the configuration section from which to read the settings.
Example

The following example creates a new LuaConfig object from a string. Usually you would read the configuration settings from the configuration file using the function get_config. It then uses the LuaConfig object to provide settings for a LuaHttpRequest named request.

local config_string = [===[
[HTTP]
ProxyHost=proxy.domain.com
ProxyPort=8080
SSLMethod=NEGOTIATE
]===]

local config = LuaConfig:new(config_string)
request:set_config(config, "HTTP")

set_header

The set_header method adds a header to the HTTP request.

Syntax
set_header( name, value )
Arguments
Argument Description
name (string) The name of the HTTP header to add to the request.
value (string or nil) The value of the HTTP header to add to the request.
Example
request:set_header("X-EXAMPLE", "Example")

set_headers

The set_headers method replaces all headers in the HTTP request with new headers.

To add a header without changing existing headers, use the method set_header.

Syntax
set_headers( headers )
Arguments
Argument Description
headers (table) The new HTTP headers to add to the request. The table must map header names to values.
Example
request:set_headers( {X-EXAMPLE="Example", X-ANOTHER="ANOTHER"} )

set_method

Specifies the HTTP request method to use when sending the request, for example GET or POST.

Syntax
set_method( method )
Arguments
Argument Description
method (string) The HTTP request method to use.
Example
request:set_method("POST")

set_url

The set_url method sets the URL that you want to send the HTTP request to.

Syntax
set_url( url )
Arguments
Argument Description
url (string) The URL to send the request to.
Example
request:set_url("https://www.example.com/")

LuaHttpResponse Methods

This section describes the methods provided by LuaHttpResponse objects. A LuaHttpResponse object is provided when you send an HTTP request using the send method on a LuaHttpRequest object.

If you have a LuaHttpResponse object called response you can call its methods using the ':' operator. For example:

response:get_http_code()
Method Description
get_body Returns the body of the HTTP response.
get_header Returns the value of the specified HTTP header.
get_headers Returns the value of all HTTP headers in the response.
get_http_code Returns the HTTP response code.

get_body

The get_body method returns the body of the HTTP response.

Syntax
get_body()
Returns

(String). The body of the HTTP response.

get_header

The get_header method returns the value of a specified HTTP header.

Syntax
get_header( name )
Arguments
Argument Description
name (string) The name of the HTTP header for which you want to get the value.
Returns

(String). The value of the header.

get_headers

The get_headers method returns the names and values of all of the headers in the HTTP response.

Syntax
get_headers()
Returns

(table) A table that maps header names to values.

Example

The following example sends an HTTP request and then prints the headers that are returned to the console:

local response = request:send()
for k,v in pairs(response:get_headers()) do
   print("HEADER:",k,v)
end

get_http_code

The get_http_code method returns the HTTP response code for the request.

Syntax
get_http_code()
Returns

(number). The response code, for example 200 for success, or 404 for not found.

LuaJsonArray Methods

A LuaJsonArray object represents a JSON array.

If you have a LuaJsonArray object called myJsonArray you can call its methods using the ':' operator. For example:

myJsonArray:size()
Constructor Description
LuaJsonArray:new The constructor for a LuaJsonArray object (creates a new LuaJsonArray).
Method Description
append Appends a value to the array.
clear Clears the array, so that it contains no values.
copy Copies the array.
empty Checks whether the array is empty.
exists Checks whether a specified path exists in the array.
existsByPath Checks whether a specified path exists in the array.
ipairs Returns an iterator function that you can use to iterate over all of the values in the array.
lookup Returns the value at a specified path in the array.
lookupByPath Returns the value at a specified path in the array.
size Returns the size of the array.
string Returns the array as a string.

LuaJsonArray:new

The constructor for a LuaJsonArray object (creates a new LuaJsonArray).

Syntax
LuaJsonArray:new( values )
Arguments
Argument Description
values (lua_json_type) The values to add to the array. Each value can be a Boolean, float, integer, string, LuaJsonArray, LuaJsonObject, LuaJsonValue, or nil.
Returns

(LuaJsonArray). The new LuaJsonArray object.

Example

The following is a simple JSON array:

[4, "a string", true]

To create a LuaJsonArray object to represent this array:

local myJsonArray = LuaJsonArray:new(4,"a string",true)

append

The append method appends a value to the JSON array.

Syntax
append( value )
Arguments
Argument Description
value (lua_json_type) The value to append to the array. This can be a Boolean, float, integer, string, LuaJsonArray, LuaJsonObject, LuaJsonValue, or nil.
Example
local myJsonArray = LuaJsonArray:new(4,"a string",true)
myJsonArray:append(6)
-- the array is now [4, "a string", true, 6]

clear

The clear method clears the array, so that it contains no values.

Syntax
clear()
Example
local myJsonArray = LuaJsonArray:new(4,"a string",true)
myJsonArray:clear()
print (myJsonArray:string())
-- []

copy

The copy method returns a copy of the array. Modifying the copy does not modify the original array.

Syntax
copy()
Returns

(LuaJsonArray). A copy of the array.

Example
local myJsonArray = LuaJsonArray:new(4,"a string",true)
local anotherJsonArray = myJsonArray:copy()
print (anotherJsonArray:string())
-- [4, "a string", true]

empty

The empty method checks whether the JSON array is empty.

Syntax
empty()
Returns

(Boolean). Returns true if the array is empty.

Example
local myJsonArray = LuaJsonArray:new(4,"a string",true)

print ("Is the array empty?  " , myJsonArray:empty() )
-- Is the array empty?   false

myJsonArray:clear()

print ("Is the array empty?  " , myJsonArray:empty() )
-- Is the array empty?   true

exists

The exists method checks whether a specified path exists in the JSON array.

Syntax
exists( pathElements )
Arguments
Argument Description
pathElements (json_path_string_or_integer) The path to check. Specify one or more path elements, which might be object attribute names (strings) or array indexes (integers).
Returns

(Boolean) Returns true if the path exists, false otherwise.

Example
local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )
local myJsonArray = LuaJsonArray:new("zero", 1, 2, myJsonObject)

print (myJsonArray:exists(0))
-- true (LuaJsonArrays are zero-indexed)

print (myJsonArray:exists(4))
-- false (LuaJsonArrays are zero-indexed, and there is no fifth value)

print (myJsonArray:exists(3, "product"))
-- true
See Also

existsByPath

The existsByPath method checks whether a specified path exists in the JSON array.

Syntax
existsByPath( path )
Arguments
Argument Description
path (string) The path to check. Construct the path from array indexes and object attribute names, and use a slash (/) as the separator. If an object attribute name includes a slash, then escape the slash with a backslash, for example "one\\/two". Notice that you must also escape a backslash with another backslash.
Returns

(Boolean) Returns true if the path exists, false otherwise.

Example
local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )
local myJsonArray = LuaJsonArray:new("zero",1,2,myJsonObject)

print (myJsonArray:existsByPath("3/product"))
-- true (LuaJsonArrays are zero-indexed)

See Also

ipairs

The ipairs method returns a function that you can use with a for loop to iterate over all of the values in the array.

Syntax
ipairs()
Example
local myJsonArray = LuaJsonArray:new(4,"a string",true)

for i, v in myJsonArray:ipairs() do
  print (v:string())
end

-- prints the following...
-- 4
-- a string
-- true

lookup

The lookup method returns the value at the specified path in the JSON array.

NOTE: This method does not make a copy of the value, so modifying the returned value affects the original array.

Syntax
lookup( pathElements )
Arguments
Argument Description
pathElements (json_path_string_or_integer) The path of the value to return. Specify one or more path elements, which might be object attribute names (strings) or array indexes (integers).
Returns

(LuaJsonValue) Returns the value that exists at the specified path, or nil if the specified path does not exist.

Example

The following example demonstrates how to obtain a value:

local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )
local myJsonArray = LuaJsonArray:new(0, 1, 2, myJsonObject)
local myValue = myJsonArray:lookup(3, "product")
print (myValue:value())
-- IDOL

The following example demonstrates how modifying a returned value affects the original array:

local myJsonObject = LuaJsonObject:new()
myJsonObject:assign("name", LuaJsonArray:new("value1"))

local myJsonArray = myJsonObject:lookup("name"):array()
myJsonArray:append("value2")

print (myJsonObject:string())
-- {"name":["value1","value2"]}
See Also

lookupByPath

The lookupByPath method returns the value at the specified path in the JSON array.

NOTE: This method does not make a copy of the value, so modifying the returned value affects the original array.

Syntax
lookupByPath( path )
Arguments
Argument Description
path (string) The path of the value to return. Construct the path from array indexes and object attribute names, and use a slash (/) as the separator. If an object attribute name includes a slash, then escape the slash with a backslash, for example "one\\/two". Notice that you must also escape a backslash with another backslash.
Returns

(LuaJsonValue) Returns the value that exists at the specified path, or nil if the specified path does not exist.

Example
local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )
local myJsonArray = LuaJsonArray:new("zero",1,2,myJsonObject)

local myValue = myJsonArray:lookupByPath("3/product")
print (myValue:value())
-- IDOL

See Also

size

The size method returns the size of the JSON array.

Syntax
size()
Returns

(integer). The number of values in the array.

Example
local myJsonArray = LuaJsonArray:new(4,"a string",true)
print ("Array size is " , myJsonArray:size() )
-- Array size is 3

string

The string method returns the JSON array as a string.

Syntax
string()
Returns

(String). The array as a string.

Example
local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )
local myJsonArray = LuaJsonArray:new("zero",1,2,myJsonObject)

print (myJsonArray:string())
-- ["zero",1,2,{"product":"IDOL","version":11}]

LuaJsonObject Methods

A LuaJsonObject object represents a JSON object.

If you have a LuaJsonObject object called object you can call its methods using the ':' operator. For example:

object:size()
Constructor Description
LuaJsonObject:new The constructor for a LuaJsonObject object (creates a new LuaJsonObject).
Method Description
assign Adds an attribute (a name/value pair) to the object.
assign Adds a table of attributes (name/value pairs) to the object.
clear Clears the object, so that it contains no attributes.
copy Copies the object.
empty Checks whether the object is empty.
erase Removes a specified attribute (name/value pair) from the object.
exists Checks whether a specified path exists in the object.
existsByPath Checks whether a specified path exists in the object.
lookup Returns the value at a specified path in the object.
lookupByPath Returns the value at a specified path in the object.
pairs Returns an iterator function that you can use to iterate over all of the attributes in the object.
size Returns the number of attributes (name/value pairs) contained in the object.
string Returns the object as a string.

LuaJsonObject:new

The constructor for a LuaJsonObject object (creates a new LuaJsonObject).

If you do not specify any attributes to assign to the object (by omitting the attributes argument), an empty object is created.

Syntax
LuaJsonObject:new( [attributes] )
Arguments
Argument Description
attributes (lua_json_object_type) A table of attributes (name/value pairs) to assign to the object. The keys in the table must be strings which specify the names of the attributes. Each value can be a Boolean, float, integer, string, LuaJsonObject, LuaJsonArray, LuaJsonValue, or nil. TIP: In Lua, keys in a table cannot be assigned the value of nil. If you want to have a null value (nil in Lua), you can do the following: LuaJsonObject:new( { key=LuaJsonValue:new(nil) } ).
Returns

(LuaJsonObject). The new LuaJsonObject object.

Example

The following is a simple JSON object:

{"product":"IDOL","version":11}

To create a LuaJsonObject object to represent this JSON object:

local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )

assign

The assign method adds an attribute (a name/value pair) to the object.

Syntax
assign (name, value)
Arguments
Argument Description
name (string) The name of the attribute to add.
value (lua_json_type) The value of the attribute to add. This can be a Boolean, float, integer, string, LuaJsonArray, LuaJsonObject, LuaJsonValue, or nil.
Example
local myJsonObject = LuaJsonObject:new( { name1="value1" , name2="value2" } )
myJsonObject:assign("name3", "value3")
myJsonObject:assign("name4", LuaJsonArray:new("value4a","value4b") )

assign

The assign method adds a table of attributes (name/value pairs) to the object.

Syntax
assign (attributes)
Arguments
Argument Description
attributes (lua_json_object_type) The table of attributes to add. The keys in the table must be strings which specify the names of the attributes to add. Each value can be a Boolean, float, integer, string, LuaJsonArray, LuaJsonObject, LuaJsonValue, or nil. TIP: In Lua, keys in a table cannot be assigned the value of nil. If you want to have a null value (nil in Lua), you can do the following: myJsonObject:assign( { key=LuaJsonValue:new(nil) } ).
Example
local myJsonObject = LuaJsonObject:new()
myJsonObject:assign( {
        attr1=LuaJsonObject:new( { n=42 } ),
        attr2=LuaJsonArray:new( 1, 2, "three" ),
        attr3=true
    } )
print(myJsonObject:string())
-- {"attr1":{"n":42},"attr2":[1,2,"three"],"attr3":true}

clear

The clear method clears the object, so that it contains no attributes (name/value pairs).

Syntax
clear()
Example
local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )
myJsonObject:clear()
print (myJsonObject:string())
-- {}

copy

The copy method returns a copy of the JSON object. Modifying the copy does not modify the original object.

Syntax
copy()
Returns

(LuaJsonObject). A copy of the object.

Example
local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )
local anotherJsonObject = myJsonObject:copy()

print (anotherJsonObject:string())
-- {"product":"IDOL","version":11}

empty

The empty method determines whether the JSON object is empty.

Syntax
empty()
Returns

(Boolean). Returns true if the object has no attributes (name/value pairs).

Example
local myJsonObject = LuaJsonObject:new()
print(myJsonObject:empty())
-- true

erase

The erase method removes a specified attribute (name/value pair) from the JSON object.

Syntax
erase( name )
Arguments
Argument Description
name (string) The name of the attribute to erase.
Example
local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )
myJsonObject:erase("version")
print (myJsonObject:string())
-- {"product":"IDOL"}

exists

The exists method checks whether a specified path exists in the JSON object.

Syntax
exists( pathElements )
Arguments
Argument Description
pathElements (json_path_string_or_integer) The path to check. Specify one or more path elements, which might be object attribute names (strings) or array indexes (integers).
Returns

(Boolean) Returns true if the path exists, false otherwise.

Example

Consider the following JSON:

{
  "product": "IDOL",
  "component": "CFS",
  "version": { "major": 11, "minor": 3 },
  "ports": [
    { "type": "ACI", "number": 7000 },
    { "type": "Service", "number": 17000 }
  ]
}

If this JSON is represented by an object named myJsonObject, you could use the exists method as follows:

print (myJsonObject:exists("ports",0,"type"))
-- true (LuaJsonArrays are zero-indexed)

print (myJsonObject:exists("ports",2,"type"))
-- false (LuaJsonArrays are zero-indexed, and there is no third value)

print (myJsonObject:exists("version", "major"))
-- true

See Also

existsByPath

The existsByPath method checks whether a specified path exists in the JSON object.

Syntax
existsByPath( path )
Arguments
Argument Description
path (string) The path to check. Construct the path from array indexes and object attribute names, and use a slash (/) as the separator. If an object attribute name includes a slash, then escape the slash with a backslash, for example "one\\/two". Notice that you must also escape a backslash with another backslash.
Returns

(Boolean) Returns true if the path exists, false otherwise.

Example

Consider the following JSON:

{
  "product": "IDOL",
  "component": "CFS",
  "version": { "major": 11, "minor": 3 },
  "ports": [
    { "type": "ACI", "number": 7000 },
    { "type": "Service", "number": 17000 }
  ]
}

If this JSON is represented by an object named myJsonObject, you could use the existsByPath method as follows:

print (myJsonObject:existsByPath("ports/0/type"))
-- true (LuaJsonArrays are zero-indexed)

print (myJsonObject:existsByPath("ports/2/type") )
-- false (LuaJsonArrays are zero-indexed, and there is no third value)

print (myJsonObject:existsByPath("version/major"))
-- true
See Also

lookup

The lookup method returns the value at the specified path in the JSON object.

NOTE: This method does not make a copy of the value, so modifying the returned value affects the original object.

Syntax
lookup( pathElements )
Arguments
Argument Description
pathElements (json_path_string_or_integer) The path of the value to return. Specify one or more path elements, which might be object attribute names (strings) or array indexes (integers).
Returns

(LuaJsonValue) Returns the value that exists at the specified path, or nil if the specified path does not exist.

Example
myJsonObject = LuaJsonObject:new()
myJsonObject:assign( {
        attr1=LuaJsonObject:new( { n=42, x=5 } ),
        attr2=LuaJsonArray:new( 1, 2, "three" ),
    } )

print ( myJsonObject:lookup("attr2",2):value() )
-- three (LuaJsonArrays are zero-indexed)

-- Modifying the returned value changes the original object
local lookup_attr = myJsonObject:lookup("attr1"):object()
lookup_attr:assign("y",3)
print (myJsonObject:string())
-- {"attr1":{"n":42,"x":5,"y":3},"attr2":[1,2,"three"]}


See Also

lookupByPath

The lookupByPath method returns the value at the specified path in the JSON object.

NOTE: This method does not make a copy of the value, so modifying the returned value affects the original object.

Syntax
lookupByPath( path )
Arguments
Argument Description
path (string) The path of the value to return. Construct the path from array indexes and object attribute names, and use a slash (/) as the separator. If an object attribute name includes a slash, then escape the slash with a backslash, for example "one\\/two". Notice that you must also escape a backslash with another backslash.
Returns

(LuaJsonValue) Returns the value that exists at the specified path, or nil if the specified path does not exist.

Example
myJsonObject = LuaJsonObject:new()
myJsonObject:assign( {
        attr1=LuaJsonObject:new( { n=42, x=5 } ),
        attr2=LuaJsonArray:new( 1, 2, "three" ),
    } )

print ( myJsonObject:lookupByPath("attr2/2"):value() )
-- three (LuaJsonArrays are zero-indexed)

-- Modifying the returned value changes the original object
local lookup_attr = myJsonObject:lookupByPath("attr1"):object()
lookup_attr:assign("y",3)
print (myJsonObject:string())
-- {"attr1":{"n":42,"x":5,"y":3},"attr2":[1,2,"three"]}
See Also

pairs

The pairs method returns an iterator function that you can use with a for loop to iterate over all of the attributes contained in the JSON object.

Syntax
pairs()
Example
local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )

for i, v in myJsonObject:pairs() do
  print (i .. '=' .. v:string())
end

-- prints the following...
-- product=IDOL
-- version=11

size

The size method returns the number of attributes (name/value pairs) in the JSON object.

Syntax
size()
Returns

(Number). The number of attributes in the JSON object.

Example
local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )
print (myJsonObject:size())
-- 2

string

The string method returns the JSON object as a string.

Syntax
string()
Returns

(String). The JSON object as a string.

Example
local myJsonObject = LuaJsonObject:new( { product="IDOL" , version=11 } )
print (myJsonObject:string())
-- {"product":"IDOL","version":11}

LuaJsonValue Methods

A LuaJsonValue object represents a JSON value.

If you have a LuaJsonValue object called myJsonValue you can call its methods using the ':' operator. For example:

myJsonValue:is_object()
Constructor Description
LuaJsonValue:new The constructor for a LuaJsonValue object (creates a new LuaJsonValue).
Method Description
array Gets a LuaJsonArray that represents the JSON array, if the value is an array.
copy Copies the value.
exists Checks whether a specified path exists in the value (when the value is a JSON array or object).
existsByPath Checks whether a specified path exists in the value (when the value is a JSON array or object).
is_array Returns whether the value is a JSON array.
is_boolean Returns whether the value is a Boolean value.
is_float Returns whether the value is a floating point value.
is_integer Returns whether the value is an integer value.
is_null Returns whether the value is a null value.
is_number Returns whether the value is a number.
is_object Returns whether the value is a JSON object.
is_simple_value Returns whether the value is a simple value (Boolean, float, integer, or string).
is_string Returns whether the value is a string value.
lookup Returns the value at a specified path (when the value is a JSON array or object).
lookupByPath Returns the value at a specified path (when the value is a JSON array or object).
object Gets a LuaJsonObject that represents the JSON object, if the value is an object.
string Returns the value as a string.
value Returns the value, if the JSON value is a simple type. If you specify a default value and the value cannot be converted to the same type as the default, the default value is returned.

LuaJsonValue:new

The constructor for a LuaJsonValue object (creates a new LuaJsonValue).

Syntax
LuaJsonValue:new( value )
Arguments
Argument Description
value (lua_json_type) The initial value. This can be a Boolean, float, integer, string, LuaJsonArray, LuaJsonObject, LuaJsonValue, or nil.
Returns

(LuaJsonValue). The new LuaJsonValue object.

array

The array method gets the array, if the value is a JSON array.

Syntax
array()
Returns

(LuaJsonArray). A LuaJsonArray object that represents the array.

Example
local fh = io.open("example_array.json", "r")
local file_content = fh:read("*all")
fh:close()
    
local myJsonValue = parse_json(file_content)

if myJsonValue:is_array() then
   print "The value is a JSON array"
   local myJsonArray=myJsonValue:array()
   print (myJsonArray:string())
end

copy

The copy method returns a copy of the value. Modifying the copy does not affect the original value.

Syntax
copy()
Returns

(LuaJsonValue). A copy of the value.

exists

The exists method checks whether a specified path exists in the JSON value.

Syntax
exists( pathElements )
Arguments
Argument Description
pathElements (json_path_string_or_integer) The path to check. Specify one or more path elements, which might be object attribute names (strings) or array indexes (integers).
Returns

(Boolean) Returns true if the path exists, false otherwise.

Example

Consider the following JSON:

{
  "product": "IDOL",
  "component": "CFS",
  "version": { "major": 11, "minor": 3 },
  "ports": [
    { "type": "ACI", "number": 7000 },
    { "type": "Service", "number": 17000 }
  ]
}

If this JSON is represented by a LuaJsonValue object named myJsonValue, you could use the exists method as follows:

print (myJsonValue:exists("ports",0,"type"))
-- true (LuaJsonArrays are zero-indexed)

print (myJsonValue:exists("ports",2,"type"))
-- false (LuaJsonArrays are zero-indexed, and there is no third value)

print (myJsonValue:exists("version", "major"))
-- true

See Also

existsByPath

The existsByPath method checks whether a specified path exists in the JSON value.

Syntax
existsByPath( path )
Arguments
Argument Description
path (string) The path to check. Construct the path from array indexes and object attribute names, and use a slash (/) as the separator. If an object attribute name includes a slash, then escape the slash with a backslash, for example "one\\/two". Notice that you must also escape a backslash with another backslash.
Returns

(Boolean) Returns true if the path exists, false otherwise.

Example

Consider the following JSON:

{
  "product": "IDOL",
  "component": "CFS",
  "version": { "major": 11, "minor": 3 },
  "ports": [
    { "type": "ACI", "number": 7000 },
    { "type": "Service", "number": 17000 }
  ]
}

If this JSON is represented by a LuaJsonValue object named myJsonValue, you could use the existsByPath method as follows:

print (myJsonValue:existsByPath("ports/0/type"))
-- true (LuaJsonArrays are zero-indexed)

print (myJsonValue:existsByPath("ports/2/type") )
-- false (LuaJsonArrays are zero-indexed, and there is no third value)

print (myJsonValue:existsByPath("version/major"))
-- true
See Also

is_array

The is_array method whether the value is a JSON array.

Syntax
is_array()
Returns

(Boolean). Returns true if the value is an array value, false otherwise.

is_boolean

The is_boolean method returns whether the value is a Boolean value.

Syntax
is_boolean()
Returns

(Boolean). Returns true if the value is a Boolean value, false otherwise.

is_float

The is_float method returns whether the value is a floating point value.

Syntax
is_float()
Returns

(Boolean). Returns true if the value is a floating point value, false otherwise.

is_integer

The is_integer method returns whether the value is an integral value.

Syntax
is_integer()
Returns

(Boolean). Returns true if the value is an integer value, false otherwise.

is_null

The is_null method returns whether the value is a null value.

Syntax
is_null()
Returns

(Boolean). Returns true if the value is a null value, false otherwise.

is_number

The is_number method returns whether the value is a number.

Syntax
is_number()
Returns

(Boolean). Returns true if the value is a number, false otherwise.

is_object

The is_object method returns whether the value is a JSON object.

Syntax
is_object()
Returns

(Boolean). Returns true if the value is a JSON object, false otherwise.

is_simple_value

The is_simple_value method returns whether the value is a simple value (Boolean, float, integer, or string).

Syntax
is_simple_value()
Returns

(Boolean). Returns true if the value is a simple value, false otherwise.

is_string

The is_string method returns whether the value is a string value.

Syntax
is_string()
Returns

(Boolean). Returns true if the value is a string value, false otherwise.

lookup

The lookup method returns the value at the specified path in the JSON value.

NOTE: This method does not make a copy of the value, so modifying the returned value affects the original object.

Syntax
lookup( pathElements )
Arguments
Argument Description
pathElements (json_path_string_or_integer) The path of the value to return. Specify one or more path elements, which might be object attribute names (strings) or array indexes (integers).
Returns

(LuaJsonValue) Returns the value that exists at the specified path, or nil if the specified path does not exist.

Example
local myJsonObject = LuaJsonObject:new()
myJsonObject:assign( {
        attr1=LuaJsonObject:new( { n=42, x=5 } ),
        attr2=LuaJsonArray:new( 1, 2, "three" ),
    } )

local myJsonValue = LuaJsonValue:new( myJsonObject )

print ( myJsonValue:lookup("attr2",2):value() )
-- three (LuaJsonArrays are zero-indexed)

-- Modifying the returned value changes the original object
local lookup = myJsonValue:lookup("attr1"):object()
lookup:assign("y",3)
print (myJsonValue:string())
-- {"attr1":{"n":42,"x":5,"y":3},"attr2":[1,2,"three"]}
See Also

lookupByPath

The lookupByPath method returns the value at the specified path in the JSON array.

NOTE: This method does not make a copy of the value, so modifying the returned value affects the original object.

Syntax
lookupByPath( path )
Arguments
Argument Description
path (string) The path of the value to return. Construct the path from array indexes and object attribute names, and use a slash (/) as the separator. If an object attribute name includes a slash, then escape the slash with a backslash, for example "one\\/two". Notice that you must also escape a backslash with another backslash.
Returns

(LuaJsonValue) Returns the value that exists at the specified path, or nil if the specified path does not exist.

Example
local myJsonObject = LuaJsonObject:new()
myJsonObject:assign( {
        attr1=LuaJsonObject:new( { n=42, x=5 } ),
        attr2=LuaJsonArray:new( 1, 2, "three" ),
    } )

local myJsonValue = LuaJsonValue:new( myJsonObject )

print ( myJsonValue:lookupByPath("attr2/2"):value() )
-- three (LuaJsonArrays are zero-indexed)

-- Modifying the returned value changes the original object
local lookup = myJsonValue:lookupByPath("attr1"):object()
lookup:assign("y",3)
print (myJsonValue:string())
-- {"attr1":{"n":42,"x":5,"y":3},"attr2":[1,2,"three"]}
See Also

object

The object method gets the object, if the value is a JSON object.

Syntax
object()
Returns

(LuaJsonObject) A LuaJsonObject object that represents the JSON object.

Example
local fh = io.open("example_json.json", "r")
local file_content = fh:read("*all")
fh:close()

local myJsonValue = parse_json(file_content)

if myJsonValue:is_object() then
   print "The value is a JSON object"
   local myJsonObject=myJsonValue:object()
   print (myJsonObject:string())
end

string

The string method returns the JSON value as a string.

Syntax
string()
Returns

(String). The JSON value as a string.

Example
local fh = io.open("example_json.json", "r")
local file_content = fh:read("*all")
fh:close()
    
local myJsonValue = parse_json(file_content)

print(myJsonValue:string())

value

The value method gets the value, if the JSON value is a simple type (a Boolean, float, integer, or string). This method returns a default value if one is specified and the value cannot be converted to the same type as the default.

Syntax
value( [default] )
Arguments
Argument Description
default (lua_json_simple_type) The default value to return, if the value cannot be converted to the same type as the default. You can specify a Boolean, float, integer, string, or nil.
Returns

(lua_json_simple_type). A Boolean, float, integer, string, or nil.

LuaLog Methods

A LuaLog object provides the capability to use a log stream. You can obtain a LuaLog object for a log stream by using the function get_log.

If you have a LuaLog object called log you can call its methods using the ':' operator. For example:

log:write_line(level, message)
Method Description
write_line Write a message to the log stream.

write_line

The write_line method writes a message to the log stream.

Syntax
write_line( level, message )
Arguments
Argument Description
level The log level for the message. The message only appears in the log if the log level specified here is the same as, or higher than, the log level set for the log stream. To obtain the correct value for the log level, use one of the following functions: * log_level_always() * log_level_error() * log_level_warning() * log_level_normal() * log_level_full()
message (string) The message to write to the log stream.
Example

To write a log message from the ExecuteDocumentLua processor in NiFi:

local log = get_log()
log:write_line(log_level_normal(), "doing something...")

-- or use the following functions
log_info("My information message")
log_warn("My warning message")
log_error("My error message")

To write a log message to an ACI Server application log:

local log = get_log("application")
log:write_line(log_level_normal(), "doing something...")

LuaLogService Methods

A LuaLogService object provides the capability to write messages to a custom log file. To write messages to standard log files, OpenText recommends using the function get_log instead.

If you have a LuaLogService object called myLogService you can call its methods using the ':' operator. For example:

myLogService:get_log("application")
Constructor Description
LuaLogService:new The constructor for a LuaLogService object (creates a new LuaLogService).
Method Description
get_log Returns a LuaLog object that you can use to write log messages to a specified log type.

LuaLogService:new

The constructor for a LuaLogService object (creates a new LuaLogService).

IMPORTANT: Do not construct a new log service to write messages to log types that are defined in the NiFi Ingest configuration file.

Syntax
LuaLogService:new( config )
Arguments
Argument Description
config (LuaConfig) The configuration object to read the logging settings from. You can obtain a LuaConfig object through the function get_config.
Returns

(LuaLogService). The new LuaLogService object.

Example

The following example creates a LuaLogService object to write log messages to a custom log file named lua.log. Declare the log service globally to avoid a LuaLogService object being created every time the script runs. For example, if you are writing a Lua script to use with a connector or CFS, create the LuaLogService outside the handler function. Otherwise, the server creates a LuaLogService object for every document that is processed.

local luaConfigString = [===[
[Logging]
LogLevel=FULL
0=LuaLogStream

[LuaLogStream]
LogTypeCSVs=lua
LogFile=lua.log
]===]
    
local config = LuaConfig:new(luaConfigString)

-- global log service instance for Lua log stream
luaLogService = LuaLogService:new(config)

local luaLog = luaLogService:get_log("lua")
luaLog:write_line(log_level_normal(), "running Lua script")

get_log

The get_log method returns a LuaLog object that you can use to write log messages to a specified log type.

Syntax
get_log( type )
Arguments
Argument Description
type (string) The log type.
Returns

(LuaLog). A LuaLog object.

LuaRegexMatch Methods

A LuaRegexMatch object provides information about the matches for a regular expression found in a string. For example, the regex_search function returns a LuaRegexMatch object.

If a match is found for a regular expression at multiple points in the string, you can use the next() method to get a LuaRegexMatch object for the next match.

If the regular expression contained sub-expressions (surrounded by parentheses) the methods of LuaRegexMatch objects can also be used to retrieve information about the sub-expression matches.

If you have a LuaRegexMatch object called match you can call its methods using the ":" operator. For example:

match:length()
Method Description
length Returns the length of the match.
next Returns a LuaRegexMatch for the next match.
position Returns the position of the match as an index from 1.
size Returns the number of sub matches for the current match.
str Returns the matched text.

length

The length method returns the length of the match. You can also retrieve the length of sub matches by specifying the submatch parameter.

Syntax
length( [ submatch ] )
Arguments
Argument Description
submatch (number) The sub match to return the length of, starting at 1 for the first sub match. With the default value of 0 the length of the whole match is returned.
Returns

(Number). The length of the sub match.

next

The next method returns a LuaRegexMatch object for the next match.

Syntax
next()
Returns

(LuaRegexMatch). A LuaRegexMatch object for the next match, or nil if there are no matches following this one.

position

The position method returns the position of the match in the string searched, where 1 refers to the first character in the string. You can also retrieve the position of sub matches by specifying the submatch parameter.

Syntax
position( [ submatch ] )
Arguments
Argument Description
submatch (number) The sub match to return the position of, starting at 1 for the first sub match. With the default value of 0 the position of the whole match is returned.
Returns

(Number). The position of the submatch as an index from 1.

size

The size method returns the total number of sub matches made for the current match, including the whole match (sub match 0).

Syntax
size()
Returns

(Number). The number of sub matches for the current match.

str

The str method returns the matched text. You can also retrieve the values of sub matches by specifying the submatch parameter.

Syntax
str( [ submatch ] )
Arguments
Argument Description
submatch (number) The sub match to return the value of, starting at 1 for the first sub match. With the default value of 0 the value of the whole match is returned.
Returns

(String). The value of the sub match.

LuaXmlDocument Methods

This section describes the methods provided by LuaXmlDocument objects. A LuaXmlDocument object provides methods for accessing information stored in XML format. You can create a LuaXmlDocument from a string containing XML using the parse_xml function.

If you have a LuaXmlDocument object called xml you can call its methods using the ':' operator. For example:

xml:root()
Method Description
root Returns a LuaXmlNode that is the root node of the XML document.
XPathExecute Returns a LuaXmlNodeSet that is the result of supplied XPath query.
XPathRegisterNs Register a namespace with the XML parser. Returns an integer detailing the error code.
XPathValue Returns the first occurrence of the value matching the XPath query.
XPathValues Returns the values according to the XPath query.

root

The root method returns an LuaXmlNode, which is the root node of the XML document.

Syntax
root()
Returns

(LuaXmlNode). A LuaXmlNode object.

XPathExecute

The XPathExecute method returns a LuaXmlNodeSet, which is the result of the supplied XPath query.

Syntax
XPathExecute( xpathQuery )
Arguments
Argument Description
xpathQuery (string) The xpath query to run.
Returns

(LuaXmlNodeSet). A LuaXmlNodeSet object.

XPathRegisterNs

The XPathRegisterNs method registers a namespace with the XML parser.

Syntax
XPathRegisterNs( prefix, location )
Arguments
Argument Description
prefix (string) The namespace prefix.
location (string) The namespace location.
Returns

(Boolean). True if successful, False in case of error.

XPathValue

The XPathValue method returns the first occurrence of the value matching the XPath query.

Syntax
XPathValue( query )
Arguments
Argument Description
query (string) The XPath query to use.
Returns

(String). A string of the value.

XPathValues

The XPathValues method returns the values according to the XPath query.

Syntax
XPathValues( query )
Arguments
Argument Description
query (string) The XPath query to use.
Returns

(Strings). The strings can be assigned to a table. To map the return values to a table, surround the function call with braces. For example:

values = { xml:XPathValues(query) }

LuaXmlNodeSet Methods

A LuaXmlNodeSet object represents a set of XML nodes.

If you have a LuaXmlNodeSet object called nodes you can call its methods using the ':' operator. For example:

nodes:size()
Method Description
at Returns the LuaXmlNode at position pos in the set.
size Returns size of node set.

at

The at method returns the LuaXmlNode at position position in the set.

Syntax
at( position )
Arguments
Argument Description
position (number) The index of the item in the array to get.
Returns

(LuaXmlNode).

size

The size method returns the size of the node set.

Syntax
size()
Returns

(Number) An integer, the size of the node set.

LuaXmlNode Methods

A LuaXmlNode object represents a single node in an XML document.

If you have a LuaXmlNode object called node you can call its methods using the ':' operator. For example:

node:name()
Method Description
attr Returns the first LuaXmlAttribute attribute object for this element.
content Returns the content (text element) of the XML node.
firstChild Returns a LuaXmlNode that is the first child of this node.
lastChild Returns a LuaXmlNode that is the last child of this node.
name Returns the name of the XML node.
next Returns a LuaXmlNode that is the next sibling of this node.
nodePath Returns the XML path to the node that can be used in another XPath query.
parent Returns the parent LuaXmlNode of the node.
prev Returns a LuaXmlNode that is the previous sibling of this node.
type Returns the type of the node as a string.

attr

The attr method returns the first LuaXmlAttribute attribute object for the LuaXmlNode. If the name argument is specified, the method returns the first LuaXmlAttribute object with the specified name.

Syntax
attr( [name] )
Arguments
Argument Description
name (string) The name of the LuaXmlAttribute object.
Returns

(LuaXmlAttribute).

content

The content method returns the content (text element) of the XML node.

Syntax
content()
Returns

(String). A string containing the content.

firstChild

The firstChild method returns the LuaXmlNode that is the first child of this node.

Syntax
firstChild()
Returns

(LuaXmlNode).

lastChild

The lastChild method returns the LuaXmlNode that is the last child of this node.

Syntax
lastChild()
Returns

(LuaXmlNode).

name

The name method returns the name of the XML node.

Syntax
name()
Returns

(String). A string containing the name.

next

The next method returns the LuaXmlNode that is the next sibling of this node.

Syntax
next()
Returns

(LuaXmlNode).

nodePath

The nodePath method returns the XML path to the node, which can be used in another XPath query.

Syntax
nodePath()
Returns

(String). A string containing the path.

parent

The parent method returns the parent LuaXmlNode of the node.

Syntax
parent()
Returns

(LuaXmlNode).

prev

The prev method returns a LuaXmlNode that is the previous sibling of this node.

Syntax
prev()
Returns

(LuaXmlNode).

type

The type method returns the type of the node as a string.

Syntax
type()
Returns

(String) A string containing the type. Possible values are:

element_node comment_node element_decl
attribute_node document_node attribute_decl
text_node document_type_node entity_decl
cdata_section_node document_frag_node namespace_decl
entity_ref_node notation_node xinclude_start
entity_node html_document_node xinclude_end
pi_node dtd_node docb_document_node

LuaXmlAttribute Methods

A LuaXmlAttribute object represents an attribute on an XML element.

If you have a LuaXmlAttribute object called attribute you can call its methods using the ':' operator. For example:

attribute:name()
Method Description
name Returns the name of this attribute.
next Returns a LuaXmlAttribute object for the next attribute in the parent element.
prev Returns a LuaXmlAttribute object for the previous attribute in the parent element.
value Returns the value of this attribute.

name

The name method returns the name of this attribute.

Syntax
name()
Returns

(String). A string containing the name of the attribute.

next

The next method returns a LuaXmlAttribute object for the next attribute in the parent element.

Syntax
next()
Returns

(LuaXmlAttribute).

prev

The prev method returns a LuaXmlAttribute object for the previous attribute in the parent element.

Syntax
prev()
Returns

(LuaXmlAttribute).

value

The value method returns the value of this attribute.

Syntax
value()
Returns

(String). A string containing the value of the attribute.


ExecuteDocumentLuaSamples — Examples

  • Generated on: 2025-08-12T06:49:03Z
  • Root: .

Table of Contents

_handler_1.lua

--[[{
    "name": "Basic handler function (LuaDocument)",
    "info": "Basic example of a handler function with a LuaDocument argument"
}]]

function handler(document)

    -- Read or write the document using any functions of LuaDocument.
    local ref = document:getReference()
    document:appendContent("Hello world")

    -- Create any new documents that are intended to be routed out of this processor.
    local newdocument = LuaDocument:new(ref..":"..create_uuid())
    
    -- Return all created documents to be routed based on the RouteReturnedTo property.
    -- By default 'document' is routed based on RouteTo property,
    --     unless it is explicitly returned.
    -- Any other documents that are not returned are discarded.
    return newdocument

end

_handler_2.lua

--[[{
    "name": "Basic handler function (LuaFlowFileDocument,LuaProcessorSession)",
    "info": "Basic example of a handler function with LuaFlowFileDocument and LuaProcessorSession arguments"
}]]

function handler(ffdocument, session)

    -- Read or write the document using any functions of LuaFlowFileDocument.
    local ref = ffdocument:getReference()
    ffdocument:modifyDocument(
        function(document)
            -- Similar to handler with only LuaDocument argument.
            -- documents or boolean may be returned and are returned by modifyDocument.
            document:appendContent("Hello world")
        end)

    -- Create any new FlowFile documents that are intended to be routed out of this processor.
    local newffdocument1 = session:create(ref..":"..create_uuid())
    local newffdocument2 = session:create(ref..":"..create_uuid())

    -- Transfer or remove FlowFile documents from the session explicitly if required
    session:transfer(newffdocument1, "success")
    session:remove(ffdocument)

    -- Return FlowFile documents to be routed based on the RouteReturnedTo property.
    -- By default 'ffdocument' is routed based on RouteTo property,
    --     unless it is explicitly returned, transferred or removed.
    -- Any FlowFile documents that are not returned, transferred or removed result in a failure.
    return newffdocument2

end

_modify_flowfile

handler_1.lua

--[[{
    "name": "Calculating hash of each file in a FlowFile document"
}]]

function handler(ffdocument, session)

    local hashFieldFromInputStream = function(inputstream, xmlmetadata)
        local hash = hash_file(
            function()
                return inputstream:read(4096)
            end,
            "MD5")
        xmlmetadata:addChild("MD5HASH"):setValue(hash)
    end

    ffdocument:append({
        onContentFile = function(action)
            action:readFile(
                function(inputstream)
                    hashFieldFromInputStream(inputstream, action:getPartXmlMetadata())
                end)
        end,
        onContentFilename = function(action)
            local inputstream = new LuaInputStream(action:getFilename())
            hashFieldFromInputStream(inputstream, action:getPartXmlMetadata())
        end})

end

handler_2.lua

--[[{
    "name": "Converting a filename part into an embedded file part"
}]]

function handler(ffdocument, session)

    ffdocument:modify({
        onContentFilename = function(action)
            action:transferFilenameToFile()
        end})

end

handler_3.lua

--[[{
    "name": "Replacing strings in the content text parts"
}]]

function handler(ffdocument, session)

    ffdocument:modify({
        onContent = function(action)
            action:transformContent(
                function(inputstream, outputstream)
                    local pageContent = inputstream:read("a")
                    local normalizedSpaces = pageContent:gsub("%s+", " ")
                    outputstream:write(normalizedSpaces)
                end)
        end})

end

handler_4.lua

--[[{
    "name": "Building XML metadata from multiple parts"
}]]

function handler(ffdocument, session)

    local metadata = nil
    local contentPageCount = 0

    ffdocument:modify({
        preAction = function(action)
            metadata = action:getXmlMetadata()
        end,
        onContent = function(action)
            action:readContent(
                function(inputstream)
                    contentPageCount = contentPageCount + 1
                end)
        end,
        onContentFile = function(action)
            metadata:addChild("FILE_PART_ID"):setValue(action:getPartId())
        end,
        onContentFilename = function(action)
            metadata:addChild("FILENAME_PART_ID"):setValue(action:getPartId())
        end,
        postAction = function(action)
            metadata:addChild("CONTENT_PAGE_COUNT"):setValue(tostring(contentPageCount))
        end})

end

handler_5.lua

--[[{
    "name": "Parse XML from the content file(name), and return new documents"
}]]

function handler(ffdocument, session)
    -- Modify the xmlParams values to match your XML
    local xmlParams = {
        document_root_paths={"documents/document"},
        reference_paths={"reference"},
        content_paths={"content"}
    }
    
    local myDocuments = {}
    
    local parseXml = function(input, isFile)
        parse_document_xml(
            input,
            isFile,
            function(document)
                table.insert(myDocuments, document) 
            end,
            xmlParams)
    end
    
    ffdocument:read({
        onContentFile = function(file)
            file:readFile(
                function(inputstream)
                    pcall(parseXml, inputstream:read('a'), false)
                end)
        end,
        onContentFilename = function(file)
            pcall(parseXml, file:getFilename(), true)
        end})
    
    return table.unpack(myDocuments)
end

handler_6.lua

--[[{
    "name": "Handling all types of file part"
}]]

function handler(ffdocument, session)

    local metadata = nil

    ffdocument:modify({
        preAction = function(action)
            metadata = action:getXmlMetadata()
        end,
        
        -- Explicitly handle embedded File parts
        onContentFile = function(action)
            metadata:addChild("FILE_PART_ID"):setValue(action:getPartId())
        end,
        
        -- Default action for onContentFile, onContentFile and onExternalFile if not explicitly set
        defaultFileAction = function(action)
            metadata:addChild("OTHERFILE_PART_ID"):setValue(action:getPartId())
        end})

end

classes_document

LuaDocument

addField.lua

--[[{
    "name": "Adding a field"
}]]

local document = LuaDocument:new("my_reference")

document:addField("my_field", "first_value")

log_info("my_field values are", document:getFieldValues("my_field"))

document:addField("my_field", "second_value")

log_info("my_field values are", document:getFieldValues("my_field"))

addSection.lua

--[[{
    "name": "Add a content text section to the document"
}]]

local document = LuaDocument:new("my_reference")

log_info("document has", document:getSectionCount(), "sections")

local document_section = document:addSection()

log_info("document_section returned of class", document_section._class_name)
log_info("document now has", document:getSectionCount(), "section")

appendContent.lua

--[[{
    "name": "Append content text to the current or specified section"
}]]
    
local document = LuaDocument:new("my_reference")

log_info("document has", document:getSectionCount(), "sections")
document:appendContent("first section content")
log_info("after append content document has", document:getSectionCount(), "section")

local document_section = document:addSection()

document_section:appendContent("second section content")
document:appendContent(" - more content", 1)

log_info("appended content to section 0 is", document:getContent(0))
log_info("appended content to section 1 is", document:getContent(1))

copyFieldNoOverwrite.lua

--[[{
    "name": "Copying a field unless destination field exists"
}]]

local document = LuaDocument:new("my_reference")
document:setFieldValue("field_to_copy", "some_value_to_copy")
document:setFieldValue("existing_result_field", "some_existing_value")

document:copyFieldNoOverwrite("field_to_copy", "existing_result_field")

log_info("result field values are", document:getFieldValues("existing_result_field"))

countField.lua

--[[{
    "name": "Count the number of a field by name"
}]]

local document = LuaDocument:new("my_reference")

document:addField("my_field", "first value")
document:addField("my_field", "second value")
document:addField("MY_FIELD", "THIRD_VALUE")

log_info("my field count is", document:countField("My_Field", false))

deleteField.lua

--[[{
    "name": "Deleting a field"
}]]

local document = LuaDocument:new("my_reference")

document:addField("my_field", "first value")
document:addField("my_field", "second value")
document:addField("MY_FIELD", "THIRD_VALUE")

document:deleteField("My_Field", "first value", false)
document:deleteField("MY_FIELD")

log_info("my field values are", document:getFieldValues("My_Field", false))

getContent.lua

--[[{
    "name": "Getting the content text for the current or specified section"
}]]

local document = LuaDocument:new("my_reference")

document:appendContent("first content")
document:appendContent("second content", 1)

log_info("document first section content is", document:getContent())
log_info("document second section content is", document:getContent(1))

getFieldNames.lua

--[[{
    "name": "Retrieving a list of field names"
}]]

local document = LuaDocument:new("my_reference")

document:addField("field_1", "field_1_value")
document:addField("field_2", "field_2_value")
document:addField("Field_2", "field_2_another_value")
document:addField("field_3", "field_3_value")
document:addField("field_3", "field_3_another_value")

log_info("document field names are", document:getFieldNames())

getFieldValue.lua

--[[{
    "name": "Getting the value of a field"
}]]

local document = LuaDocument:new("my_reference")

document:addField("my_Field", "first value")
document:addField("my_field", "second value")
document:addField("my_field", "third value")

log_info("my_field value is", document:getFieldValue("my_field"))
log_info("my_field value case insensitive is", document:getFieldValue("my_field", false))

getFieldValues.lua

--[[{
    "name": "Retrieving field values for a field name"
}]]

local document = LuaDocument:new("my_reference")

document:addField("my_Field", "first value")
document:addField("my_field", "second value")
document:addField("my_field", "third value")

log_info("my_field values are", document:getFieldValues("my_field"))
log_info("my_field values case insensitive are", document:getFieldValues("my_field", false))

getNextSection.lua

--[[{
    "name": "Getting the next LuaDocumentSection for a document"
}]]

local document = LuaDocument:new("my_reference")
document:appendContent("first")
document:appendContent("second", 1)
document:appendContent("third", 2)

local section = document
while section do
    log_info("section content is", section:getContent())
    section = section:getNextSection()
end

getReference.lua

--[[{
    "name": "Getting the reference value of a document"
}]]

local document = LuaDocument:new("my_reference")

local reference = document:getReference()

log_info("document reference is", reference)

getSection.lua

--[[{
    "name": "Getting a LuaDocumentSection for a section number"
}]]

local document = LuaDocument:new("my_reference")
document:appendContent("first")
document:appendContent("second", 1)
document:appendContent("third", 2)

local section = document:getSection(1)

log_info("section returned of class", section._class_name)
log_info("section content is", section:getContent())

getSectionCount.lua

--[[{
    "name": "Retrieving a count of the sections in a document"
}]]

local document = LuaDocument:new("my_reference")
document:appendContent("first")
document:appendContent("second", 1)
document:appendContent("third", 2)

local sectionCount = document:getSectionCount()

log_info("document has", sectionCount, "sections")

hasField.lua

--[[{
    "name": "Test whether a field exists"
}]]

local document = LuaDocument:new("my_reference")
document:addField("my_field", "value")

log_info("document has field my_field case sensitive is", document:hasField("my_field"))
log_info("document has field MY_field case sensitive is", document:hasField("MY_field"))
log_info("document has field MY_field case insensitive is", document:hasField("MY_field", false))

insertJson.lua

--[[{
    "name": "Inserting JSON data into a document"
}]]

local document = LuaDocument:new("my_reference")

local json_string = '{"field_1":"value_1","field_2":{"sub_field":"value_2"}}'
local json = parse_json_object(json_string)

document:insertJson(json, "root_field")

log_info("root_field/field_1 value is", document:getField("root_field"):getField("field_1"):value())
log_info("root_field/field_2/sub_field value is", document:getField("root_field"):getField("field_2"):getField("sub_field"):value())

insertXml.lua

--[[{
    "name": "Inserting XML structured fields as a field"
}]]

local document = LuaDocument:new("my_reference")

local xml_string = "<root><field_1>value_1</field_1><field_2><sub_field>value_2</sub_field></field_2></root>"
local xml = parse_xml(xml_string)

document:insertXml(xml:root(), "root_field")

log_info("root_field/field_1 value is", document:getField("root_field"):getField("field_1"):value())
log_info("root_field/field_2/sub_field value is", document:getField("root_field"):getField("field_2"):getField("sub_field"):value())

insertXmlWithoutRoot.lua

--[[{
    "name": "Inserting XML structured fields into a field without the root"
}]]

local document = LuaDocument:new("my_reference")

local xml_string = "<root><field_1>value_1</field_1><field_2><sub_field>value_2</sub_field></field_2></root>"
local xml = parse_xml(xml_string)

document:insertXmlWithoutRoot(xml:root())

log_info("field_1 value is", document:getFieldValue("field_1"))
log_info("field_2/sub_field value is", document:getField("field_2"):getField("sub_field"):value())

new.lua

--[[{
    "name": "Creating a new LuaDocument with a specified reference"
}]]

local reference = "my_reference"

local document = LuaDocument:new(reference)

log_info("document returned of class", document._class_name)

removeSection.lua

--[[{
    "name": "Removing a section from a document by section number"
}]]

local document = LuaDocument:new("my_reference")
document:appendContent("bad content")
document:appendContent("good content", 1)

document:removeSection(0)

log_info("first section content is", document:getContent(0))

renameField_1.lua

--[[{
    "name": "Case-sensitive renaming of a field"
}]]

local document = LuaDocument:new("my_reference")
document:addField("MY_field", "first value")
document:addField("my_field", "second value")

local renamedFields = { document:renameField("MY_field", "YOUR_field") }

log_info("renamed field count is", #renamedFields)
log_info("document field names are", document:getFieldNames())
log_info("renamed field values are", document:getFieldValues("YOUR_field"))

renameField_2.lua

--[[{
    "name": "Case-insensitive renaming of a field"
}]]

local document = LuaDocument:new("my_reference")
document:addField("MY_field", "first value")
document:addField("my_field", "second value")

local renamedFields = { document:renameField("MY_field", "YOUR_field", false) }

log_info("renamed field count is", #renamedFields)
log_info("document field names are", document:getFieldNames())
log_info("renamed field values are", document:getFieldValues("YOUR_field"))

setContent.lua

--[[{
    "name": "Setting the content text for the current or specified section"
}]]

local document = LuaDocument:new("my_reference")

document:setContent("third section content", 2)
document:setContent("first section content")

log_info("section 0 content is", document:getContent(0))
log_info("section 1 content is", document:getContent(1))
log_info("section 2 content is", document:getContent(2))

setFieldValue.lua

--[[{
    "name": "Setting the value of a field"
}]]

local document = LuaDocument:new("my_reference")

document:setFieldValue("my_field", "some_value")

log_info("my_field value is", document:getFieldValue("my_field"))

setReference.lua

--[[{
    "name": "Setting the reference value of a document"
}]]

local document = LuaDocument:new("my_reference")

document:setReference("new_reference")

log_info("document reference is", document:getReference())

to_idx.lua

--[[{
    "name": "Converting a document to an IDX string"
}]]

local document = LuaDocument:new("my_reference")

document:setFieldValue("my_field_1", "value_1")
document:setFieldValue("my_field_1", "value_2")
document:getField("my_field_2"):getField("sub_field"):setValue("sub_field_value")
document:setContent("my content")

log_info("document as idx is", document:to_idx())

to_json.lua

--[[{
    "name": "Converting a document to a JSON string"
}]]

local document = LuaDocument:new("my_reference")

document:setFieldValue("my_field_1", "value_1")
document:setFieldValue("my_field_1", "value_2")
document:getField("my_field_2"):getField("sub_field"):setValue("sub_field_value")
document:setContent("my content")

log_info("document as json is", document:to_json())

to_xml.lua

--[[{
    "name": "Converting a document to an XML string"
}]]

local document = LuaDocument:new("my_reference")

document:setFieldValue("my_field_1", "value_1")
document:setFieldValue("my_field_1", "value_2")
document:getField("my_field_2"):getField("sub_field"):setValue("sub_field_value")
document:setContent("my content")

log_info("document as xml is", document:to_xml())

LuaField

addField.lua

--[[{
    "name": "Adding a field"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

field:addField("my_field", "first_value")

log_info("my_field values are", field:getFieldValues("my_field"))

field:addField("my_field", "second_value")

log_info("my_field values are", field:getFieldValues("my_field"))

copyFieldNoOverwrite.lua

--[[{
    "name": "Copying a field unless destination field exists"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

field:getField("field_to_copy"):setValue("some_value_to_copy")
field:getField("existing_result_field"):setValue("some_existing_value")

field:copyFieldNoOverwrite("field_to_copy", "existing_result_field")

log_info("result field values are", field:getFieldValues("existing_result_field"))

countField.lua

--[[{
    "name": "Count the number of a field by name"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

field:addField("my_field", "first value")
field:addField("my_field", "second value")
field:addField("MY_FIELD", "THIRD_VALUE")

log_info("my field count is", field:countField("My_Field", false))

deleteAttribute.lua

--[[{
    "name": "Deleting an attribute"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")
field:setAttributeValue("attr_1", "attribute value")

log_info("field has attribute attr_1 is", field:hasAttribute("attr_1"))

field:deleteAttribute("attr_1");

log_info("field has attribute attr_1 is", field:hasAttribute("attr_1"))

deleteField.lua

--[[{
    "name": "Deleting a field"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

field:addField("my_field", "first value")
field:addField("my_field", "second value")
field:addField("MY_FIELD", "THIRD_VALUE")

field:deleteField("My_Field", "first value", false)
field:deleteField("MY_FIELD")

log_info("my field values are", field:getFieldValues("My_Field", false))

getAttributeValue.lua

--[[{
    "name": "Getting the value of an attribute"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

log_info("unset field attribute value is", field:getAttributeValue("attr_1"))

field:setAttributeValue("attr_1", "attribute value")

log_info("field attribute value is", field:getAttributeValue("attr_1"))

getFieldNames.lua

--[[{
    "name": "Retrieving a list of field names"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

field:addField("field_1", "field_1_value")
field:addField("field_2", "field_2_value")
field:addField("Field_2", "field_2_another_value")
field:addField("field_3", "field_3_value")
field:addField("field_3", "field_3_another_value")

log_info("field field names are", field:getFieldNames())

getFieldValues.lua

--[[{
    "name": "Retrieving field values for a field name"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

field:addField("my_Field", "first value")
field:addField("my_field", "second value")
field:addField("my_field", "third value")

log_info("my_field values are", field:getFieldValues("my_field"))
log_info("my_field values case insensitive are", field:getFieldValues("my_field", false))

hasAttribute.lua

--[[{
    "name": "Test whether an attribute exists"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

if not field:hasAttribute("attr_1") then
    log_info("field does not have attribute attr_1")
end

field:setAttributeValue("attr_1", "attribute value")

if field:hasAttribute("attr_1") then
    log_info("field has attribute attr_1")
end

hasField.lua

--[[{
    "name": "Test whether a field exists"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")
field:addField("my_field", "value")

log_info("field has field my_field case sensitive is", field:hasField("my_field"))
log_info("field has field MY_field case sensitive is", field:hasField("MY_field"))
log_info("field has field MY_field case insensitive is", field:hasField("MY_field", false))

insertXml.lua

--[[{
    "name": "Inserting XML structured fields as a field"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

local xml_string = "<root><field_1>value_1</field_1><field_2><sub_field>value_2</sub_field></field_2></root>"
local xml = parse_xml(xml_string)

field:insertXml(xml:root(), "root_field")

log_info("root_field/field_1 value is", field:getField("root_field"):getField("field_1"):value())
log_info("root_field/field_2/sub_field value is", field:getField("root_field"):getField("field_2"):getField("sub_field"):value())

insertXmlWithoutRoot.lua

--[[{
    "name": "Inserting XML structured fields into a field without the root"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

local xml_string = "<root><field_1>value_1</field_1><field_2><sub_field>value_2</sub_field></field_2></root>"
local xml = parse_xml(xml_string)

field:insertXmlWithoutRoot(xml:root())

log_info("field_1 value is", field:getField("field_1"):value())
log_info("field_2/sub_field value is", field:getField("field_2"):getField("sub_field"):value())

name.lua

--[[{
    "name": "Getting the name of a field"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

log_info("field name is", field:name())

renameField_1.lua

--[[{
    "name": "Case-sensitive renaming of a field"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")
field:addField("MY_field", "first value")
field:addField("my_field", "second value")

local renamedFields = { field:renameField("MY_field", "YOUR_field") }

log_info("renamed field count is", #renamedFields)
log_info("field field names are", field:getFieldNames())
log_info("renamed field values are", field:getFieldValues("YOUR_field"))

renameField_2.lua

--[[{
    "name": "Case-insensitive renaming of a field"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")
field:addField("MY_field", "first value")
field:addField("my_field", "second value")

local renamedFields = { field:renameField("MY_field", "YOUR_field", false) }

log_info("renamed field count is", #renamedFields)
log_info("field field names are", field:getFieldNames())
log_info("renamed field values are", field:getFieldValues("YOUR_field"))

setAttributeValue.lua

--[[{
    "name": "Setting the value of an attribute"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

field:setAttributeValue("attr_1", "attribute value")

log_info("field attributes value is", field:getAttributeValue("attr_1"))

setValue.lua

--[[{
    "name": "Setting the value of a field"
}]]

local document = LuaDocument:new("my_reference")
local field = document:getField("doc_field")

field:setValue("new value")

log_info("field value is", field:value())

value.lua

--[[{
    "name": "Getting the value of a field"
}]]

local document = LuaDocument:new("my_reference")
document:setFieldValue("doc_field", "my_value")

local field = document:getField("doc_field")

log_info("field value is", field:value())

LuaFieldContainer

copyField.lua

--[[{
    "name": "Copying fields"
}]]

local document = LuaDocument:new("my_reference")
document:addField("MY_field", "first value")
document:addField("my_field", "second value")
local field = document:getField("doc_field")
field:addField("MY_field", "first value")
field:addField("my_field", "second value")

-- case sensitive lookup
local document_new_field = { document:copyField("my_field", "new_field") }
local field_new_field = { field:copyField("my_field", "new_field") }

-- case insensitive lookup
local document_new_fields = { document:copyField("my_field", "new_fields", false) }
local field_new_fields = { field:copyField("my_field", "new_fields", false) }

getField.lua

--[[{
    "name": "Retieving a field by name, creating if non-existent"
}]]

local document = LuaDocument:new("my_reference")
document:setFieldValue("FIRST_field", "first value")

local first_field = document:getField("first_field")
log_info("field returned of class", first_field._class_name)

case_insensitive_first_field = document:getField("first_field", false)
log_info("case insensitive field value is", case_insensitive_first_field:value())

local second_field = first_field:getField("second_field")

log_info("second field returned of class", second_field._class_name)
if first_field:hasField("second_field") then
    log_info("first_field/second_field exists")
end

getFields.lua

--[[{
    "name": "Retieving all fields by name"
}]]

local document = LuaDocument:new("my_reference")
document:addField("MY_field", "first value")
document:addField("my_field", "second value")
local field = document:getField("doc_field")
field:addField("MY_field", "first value")
field:addField("my_field", "second value")

-- case sensitive lookup
local document_my_field = { document:getFields("my_field") }
local field_my_field = { field:getFields("my_field") }

-- case insensitive lookup
local document_my_fields = { document:getFields("my_field", false) }
local field_my_fields = { field:getFields("my_field", false) }

getValueByPath.lua

--[[{
    "name": "Retrieve a field or attribute value by path string"
}]]

local document = LuaDocument:new("my_reference")
local field_1 = document:getField("field_1")
local field_2 = field_1:getField("field_2")
local field_3 = field_2:getField("field_3")
field_3:addField("my_field", "field value")
field_3:setAttributeValue("my_attribute", "attribute value")

local attribute_value = document:getValueByPath("field_1/field_2/field_3/@my_attribute")

log_info("document field_1/field_2/field_3/@my_attribute value is", attribute_value)

local field_value = document:getValueByPath("field_1/field_2/field_3/my_field")

log_info("document field_1/field_2/field_3/my_field value is", field_value)

attribute_value = field_2:getValueByPath("field_3/@my_attribute")

log_info("field_2 field_3/@my_attribute value is", attribute_value)

field_value = field_2:getValueByPath("field_3/my_field")

log_info("field_2 field_3/my_field value is", field_value)

getValuesByPath.lua

--[[{
    "name": "Retrieve field or attribute values by path string"
}]]

local document = LuaDocument:new("my_reference")
local field_1 = document:getField("field_1")
local field_2a = field_1:addField("field_2", "")
local field_2b = field_1:addField("field_2", "")
field_2a:addField("my_field", "field_value_1")
field_2b:addField("my_field", "field_value_2")
field_2a:setAttributeValue("my_attribute", "attribute_value_1")
field_2b:setAttributeValue("my_attribute", "attribute_value_2")

local attribute_values = { document:getValuesByPath("field_1/field_2/@my_attribute") }
local field_values = { document:getValuesByPath("field_1/field_2/my_field") }
local relative_attribute_values = { field_1:getValuesByPath("field_2/@my_attribute") }
local relative_field_values = { field_1:getValuesByPath("field_2/my_field") }

classes_flowfile

LuaFlowFileDocument

append_1.lua

--[[{
    "name": "Appending new parts to a FlowFile document"
}]]

function handler(ffdocument, session)

    -- Adds a content part and appends replacement XML metadata
    ffdocument:append(function(action)
            action:addContent("Hello world")
            action:getXmlMetadata():addChild("said_hello"):setValue("true")
        end)

end

append_2.lua

--[[{
    "name": "Appending new parts to replace existing parts in a FlowFile document"
}]]

function handler(ffdocument, session)

    ffdocument:append({
        -- preAction = function(action) do_nothing end,
        -- onContent = function(action) do_nothing end,
        onContentFile = function(action)
            action:writeFile(function(outputstream)
                    outputstream:write("This file content has been overwritten")
                end)
        end,
        
        onContentFilename = function(action)
            action:deletePart()
        end
        --, postAction = function(action) do_nothing end
        })

end

attributes.lua

--[[{
    "name": "Getting and setting attributes on a FlowFile"
}]]

function handler(ffdocument, session)

    local reference = ffdocument:getReference()             -- idol.reference
    local referenceAction = ffdocument:getReferenceAction() -- idol.reference.action

    local state = ffdocument:getAttribute("luahandlerstate")
    
    if state ~= "done" then
        
        ffdocument:setAttributes( { luahandlerstate = "done" } )
        
    end

end

compact.lua

--[[{
    "name": "Stripping parts marked for removal from a FlowFile document"
}]]

function handler(ffdocument, session)

    local deleteParts = function(action)
        action:deletePart()
    end
    
    -- Mark all files for removal in the FlowFile document
    ffdocument:append({
        onContentFile = deleteParts,
        onContentFilename = deleteParts})
    
    -- Remove parts marked for removal
    ffdocument:compact()
    
    -- note: calling append and then compact is equivalent to just calling modify

end

filecount.lua

--[[{
    "name": "Counting file or filename parts in a FlowFile"
}]]

function handler(ffdocument, session)

    -- Number of binary files embedded in the FlowFile
    local filePartCount = ffdocument:getFileCount()
    
    -- Number of local file references in the FlowFile
    local filenamePartCount = ffdocument:getFilenameCount()

end

modify.lua

--[[{
    "name": "Modifying parts in a FlowFile document"
}]]

function handler(ffdocument, session)

    local allContent = ""
    ffdocument:modify({
        -- preAction = function(action) do_nothing end,
        onContent = function(action)
            action:readContent(function(inputstream)
                    allContent = allContent .. "\012" .. inputstream:read("a")
                end)
        end,
        
        onContentFile = function(action)
            action:writeFile(function(outputstream)
                    outputstream:write("This file content has been overwritten")
                end)
        end,
        
        onContentFilename = function(action)
            action:transferFilenameToFile()
        end,
        
        postAction = function(action)
            action:getXmlMetadata():addChild("CONTENT_MD5"):setValue(hash_string(allContent))
        end})

end

modifydocument.lua

--[[{
    "name": "Modifying a FlowFile using a LuaDocument handler"
}]]

function handler(ffdocument, session)

    local luaDocumentHander = function(document)
        document:appendContent("Hello world")
        return true
    end

    local result = ffdocument:modifyDocument(luaDocumentHander)
    
    if not result then
        session:remove(ffdocument)
    end

end

overwrite.lua

--[[{
    "name": "Overwriting an entire FlowFile document with new parts"
}]]

function handler(ffdocument, session)

    -- Overwrite FlowFile with a single text content part
    ffdocument:overwrite(function(action)
            action:addContent("Hello world")
        end)

end

read.lua

--[[{
    "name": "Reading parts in a FlowFile document"
}]]

function handler(ffdocument, session)

    local hashes = {}
    ffdocument:read({
        -- preAction = function(action) do_nothing end,
        onContent = function(action)
            action:readContent(function(inputstream)
                    local pageContent = inputstream:read("a")
                    hashes:insert(hash_string(pageContent))
                end)
        end,
        
        onContentFile = function(action)
            action:readFile(function(inputstream)
                    local fileContent = inputstream:read("a")
                    hashes:insert(hash_string(fileContent))
                end)
        end,
        
        onContentFilename = function(action)
            local f = assert(io.open(action:getFilename()))
            local fileContent = f:read("a")
            f:close()
            hashes:insert(hash_string(fileContent))
        end
        --, postAction = function(action) do_nothing end
        })

end

tofromdocument.lua

--[[{
    "name": "Converting LuaFlowFileDocument to and from LuaDocument"
}]]

function handler(ffdocument, session)

    local document = ffdocument:getAsLuaDocument()
    
    -- Updates to document are not mirrored by ffdocument
    -- The ffdocument must be updated after changes are completed
    
    ffdocument:setFromLuaDocument(document)

end

LuaProcessorSession

connection.lua

--[[{
    "name": "Testing whether a connection exists and has available space"
}]]

function handler(ffdocument, session)

    if session:hasConnection("session") then
        log_info("Relationship session is connected")
        
        if session:relationshipAvailable("session") then
            log_info("Relationship session has available space")
        end
    end

end

create.lua

--[[{
    "name": "Creating a new FlowFile document"
}]]

function handler(ffdocument, session)

    local ref = ffdocument:getReference()

    -- With only idol.reference attribute
    local newffdocument1 = session:create(ref..":"..create_uuid())
    
    -- Also with idol.reference.action and parent FlowFile specified
    local newffdocument2 = session:create(ref..":"..create_uuid(), "add", ffdocument)
    
    return newffdocument1, newffdocument2

end

getname.lua

--[[{
    "name": "Getting the name of the processor"
}]]

function handler(ffdocument, session)

    local processorName = session:getName()

    log_info(processorName)

end

getqueuesize.lua

--[[{
    "name": "Getting the size of the processor input queue"
}]]

function handler(ffdocument, session)

    local queueSize = session:getQueueSize()

    log_info("QueueSize:", queueSize)

end

remove.lua

--[[{
    "name": "Removing a FlowFile from the session"
}]]

function handler(ffdocument, session)

    local ref = ffdocument:getReference()
    
    local newffdocument = session:create(ref..":"..create_uuid())
    
    -- remove original FlowFile
    session:remove(ffdocument)

    return newffdocument

end

transfer.lua

--[[{
    "name": "Transferring a FlowFile from the session"
}]]

function handler(ffdocument, session)

    local ref = ffdocument:getReference()
    
    local newffdocument = session:create(ref..":"..create_uuid())
    
    session:transfer(newffdocument, "success")
    
    -- transfer original back to input queue to be processed again
    session:transfer(ffdocument)

end

classes_http

LuaHttpRequest

new_1.lua

--[[{
    "name": "Creating a new HTTP request"
}]]

local request = LuaHttpRequest:new()

log_info("http request returned of class", request._class_name)

new_2.lua

--[[{
    "name": "Creating a new HTTP request with configuration"
}]]

local config_string = 
[===[
[http]
ProxyHost=someproxy
ProxyPort=8080
]===]

local config = LuaConfig:new(config_string)

local request = LuaHttpRequest:new(config, "http")

log_info("http request returned of class", request._class_name)

send.lua

--[[{
    "name": "Sending an HTTP request"
}]]

local request = LuaHttpRequest:new()

request:set_url("http://some.site/thing")

local response = request:send()

log_info("http response returned of class", response._class_name)

set_config.lua

--[[{
    "name": "Setting the configuration for an HTTP request"
}]]

local request = LuaHttpRequest:new()

local config_string = 
[===[
[http]
ProxyHost=someproxy
ProxyPort=8080
]===]

local config = LuaConfig:new(config_string)

request:set_config(config, "http")

set_request_details.lua

--[[{
    "name": "Setting the request details for an HTTP request"
}]]

local request = LuaHttpRequest:new()

request:set_method("PUT")
request:set_url("http://some.site/put_thing")
request:set_header("header1", "value1")
request:set_headers({["header2"]="value2", ["header3"]="value3"})
request:set_body("<data>Data to put</data>")

LuaHttpResponse

get_http_code.lua

--[[{
    "name": "Getting the HTTP response code"
}]]

local request = LuaHttpRequest:new()
request:set_url("http://some.site/thing")

local response = request:send()

local http_code = response:get_http_code()

log_info("responded with http code", http_code)

get_response_details.lua

--[[{
    "name": "Getting the HTTP response headers and body"
}]]

local request = LuaHttpRequest:new()
request:set_url("http://some.site/thing")

local response = request:send()

if 200 == response:get_http_code() then
    local oneHeader = response:get_header("header1")
    local headersTable = response:get_headers()
    local body = response:get_body()
end

classes_json

LuaJsonArray

append.lua

--[[{
    "name": "Appending values to a JSON array"
}]]

local json_array = LuaJsonArray:new()

json_array:append("value", true, 2, LuaJsonObject:new())

clear.lua

--[[{
    "name": "Clear the values from a JSON array"
}]]

local json = '{"arr":[7]}'
local json_value = parse_json(json)

json_value:lookup("arr"):array():clear()

log_info(json_value:string())

copy.lua

--[[{
    "name": "Copying a JSON array"
}]]

local json = '{"arr1":[7]}'
local json_value = parse_json(json)

local copy_of_array = json_value:lookup("arr1"):array():copy()

copy_of_array:append(8, 9)

json:assign("arr2", copy_of_array)

log_info(json_value:string())

empty.lua

--[[{
    "name": "Testing whether a JSON array is empty"
}]]

local json = '[]'

local json_array = parse_json_array(json)

if json_array:empty() then
    log_info("JSON array is empty")
end

ipairs.lua

--[[{
    "name": "Looping over JSON array values in a for loop"
}]]

local json = '[3,1,4,5,9,2,6,8,7,0]'

local json_array = parse_json_array(json)

for i, v in json_array:ipairs() do
    log_info(v:string())
end

new.lua

--[[{
    "name": "Creating a new JSON array"
}]]

local json_array = LuaJsonArray:new("value", true, 2, LuaJsonObject:new())

log_info(json_array:string())

size.lua

--[[{
    "name": "Getting the size of a JSON array"
}]]

local json = '[1,2,3,4,5,6,7]'

local json_array = parse_json_array(json)

local array_size = json_array:size()

log_info("JSON array has size", array_size)

LuaJsonBase

exists.lua

--[[{
    "name": "Testing existence of JSON object attributes or array entries"
}]]

local json = '{"obj":{"arr":[7]}}'

local json_value = parse_json(json)

if json_value:exists("obj") then
    log_info("JSON object contains attribute 'obj'")
    
    if json_value:lookup("obj"):exists("arr", 0) then
        log_info("JSON object 'obj' contains attribute 'arr' with at least one array entry")
    end
end

existsByPath.lua

--[[{
    "name": "Testing existence of JSON object attributes or array entries by path"
}]]

local json = '{"obj":{"arr":[7]}}'

local json_value = parse_json(json)

if json_value:existsByPath("obj/arr/0") then
    log_info("JSON object contains 'obj' object with 'arr' attribute with at least one array entry")
end

is_type.lua

--[[{
    "name": "Testing the type of a JSON value"
}]]

local json = [===[{
    "array": [1,2,3],
    "boolean": true,
    "integer": 196,
    "float": 2.7,
    "null": null,
    "object": {},
    "string": "um"
}]===]

local json_value = parse_json(json)

log_info("array is_array:", json_value:lookup("array"):is_array())
log_info("boolean is_boolean:", json_value:lookup("boolean"):is_boolean())
log_info("integer is_integer:", json_value:lookup("integer"):is_integer())
log_info("float is_float:", json_value:lookup("float"):is_float())
log_info("null is_null:", json_value:lookup("null"):is_null())
log_info("float is_number:", json_value:lookup("float"):is_number())
log_info("object is_object:", json_value:lookup("object"):is_object())
log_info("integer is_simple_value:", json_value:lookup("integer"):is_simple_value())
log_info("string is_string:", json_value:lookup("string"):is_string())

lookup.lua

--[[{
    "name": "Looking up JSON object attributes or array entries"
}]]

local json = '{"obj":{"arr":[7]}}'

local json_value = parse_json(json)

local obj_value = json_value:lookup("obj")
local arr_first_value = obj_value:lookup("arr", 0)

log_info("JSON array first value is", arr_first_value)

lookupByPath.lua

--[[{
    "name": "Looking up JSON object attributes or array entries by path"
}]]

local json = '{"obj":{"arr":[7]}}'

local json_value = parse_json(json)

local arr_first_value = json_value:lookupByPath("obj/arr/0")

log_info("JSON array first value is ", arr_first_value)

string.lua

--[[{
    "name": "Converting JSON value to a string"
}]]

local json = '{"obj":{"arr":[7]}}'

local json_value = parse_json(json)

local json_as_string = json_value:string()

if json == json_as_string then
    log_info("json_value:string() matches original string")
end

LuaJsonObject

assign.lua

--[[{
    "name": "Assigning values to a JSON object"
}]]

local json_object = LuaJsonObject:new()

local json_attributes = {one:1, two:2, three:3}

json_object:assign(json_attributes)
json_object:assign("four", 4)

clear.lua

--[[{
    "name": "Clear the entries from a JSON object"
}]]

local json = '{"obj":{"one":1}}'
local json_value = parse_json(json)

json_value:lookup("obj"):object():clear()

log_info(json_value:string())

copy.lua

--[[{
    "name": "Copying a JSON object"
}]]

local json = '{"one":1, "two":2, "three":3}'
local json_object = parse_json_object(json)

local copy_of_object = json_object:copy()

json_object:erase("three")

log_info(copy_of_object:string())

empty.lua

--[[{
    "name": "Testing whether a JSON object is empty"
}]]

local json = '{}'

local json_object = parse_json_object(json)

if json_object:empty() then
    log_info("JSON object is empty")
end

erase.lua

--[[{
    "name": "Erasing attributes from a JSON object"
}]]

local json = '{"one":1, "two":2, "three":3}'

local json_object = parse_json_object(json)

json_object:erase("two", "three")

log_info(json_object:string())

new_1.lua

--[[{
    "name": "Creating a new empty JSON object"
}]]

local json_object = LuaJsonObject:new()

log_info(json_object:string())

new_2.lua

--[[{
    "name": "Creating a new JSON object from a table"
}]]

local json_attributes = {one:1, two:2, three:3}

local json_object = LuaJsonObject:new(json_attributes)

log_info(json_object:string())

pairs.lua

--[[{
    "name": "Looping over JSON object entries in a for loop"
}]]

local json = '{"one":1, "two":2, "three":3}'

local json_object = parse_json_object(json)

for k, v in json_object:pairs() do
    log_info(k.."="..v:string())
end

size.lua

--[[{
    "name": "Getting the size of a JSON object"
}]]

local json = '{"one":1, "two":2, "three":3}'

local json_object = parse_json_object(json)

local object_size = json_object:size()

log_info("JSON object has size", object_size)

LuaJsonValue

array.lua

--[[{
    "name": "Interpret a JSON value as a JSON array"
}]]

local json = '[1,2,3,4,5]'

local json_value = parse_json(json)

local json_array = json_value:array()

copy.lua

--[[{
    "name": "Copying a JSON value"
}]]

local json = '{"obj":{"arr":[7]}}'

local json_value = parse_json(json)

local json_value_copy = json_value:copy()

new.lua

--[[{
    "name": "Creating a new JSON value"
}]]

local null_value = LuaJsonValue:new(nil)
local boolean_value = LuaJsonValue:new(true)
local integer_value = LuaJsonValue:new(196)
local float_value = LuaJsonValue:new(2.7)
local string_value = LuaJsonValue:new("value")
local object_value = LuaJsonValue:new(LuaJsonObject:new())
local array_value = LuaJsonValue:new(LuaJsonArray:new())

object.lua

--[[{
    "name": "Interpret a JSON value as a JSON object"
}]]

local json = '{"attr": "value"}'

local json_value = parse_json(json)

local json_object = json_value:object()

value_1.lua

--[[{
    "name": "Convert a JSON value containing a simple type to that type"
}]]

local json = '{"seven":7}'

local json_value = parse_json(json)

local json_seven_value = json_value:lookup("seven")

local number_seven = json_seven_value:value();

value_2.lua

--[[{
    "name": "Convert a JSON value to simple type with a default value"
}]]

local json = '{}'

local json_value = parse_json(json)

local json_seven_value = json_value:lookup("seven")

local number_seven = json_seven_value:value(7);

classes_xml

LuaXmlAttribute

name.lua

--[[{
    "name": "Getting the name of an XML attribute"
}]]

local xml = "<root attr0=\"attr0value\" attr1=\"attr1value\" attr2=\"attr2value\"></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()
    local xml_attribute = xml_node:attribute() -- The first attribute

    log_info("xml_attribute:name returned", xml_attribute:name())
else
    log_info("parse xml failed", xml)
end

next.lua

--[[{
    "name": "Getting the next attribute"
}]]

local xml = "<root attr0=\"attr0value\" attr1=\"attr1value\" attr2=\"attr2value\"></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()
    local xml_attribute = xml_node:attribute("attr1")
    local next_xml_attribute = xml_attribute:next()

    log_info("xml_attribute:next returned of type", next_xml_attribute._class_name)
    log_info("next xml_attribute name", next_xml_attribute:name())
else
    log_info("parse xml failed", xml)
end

previous.lua

--[[{
    "name": "Getting the previous attribute"
}]]

local xml = "<root attr0=\"attr0value\" attr1=\"attr1value\" attr2=\"attr2value\"></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()
    local xml_attribute = xml_node:attribute("attr1")
    local prev_xml_attribute = xml_attribute:previous()

    log_info("xml_attribute:previous returned of type", prev_xml_attribute._class_name)
    log_info("previous xml_attribute name", prev_xml_attribute:name())
else
    log_info("parse xml failed", xml)
end

value.lua

--[[{
    "name": "Getting the value of an attribute"
}]]

local xml = "<root attr0=\"attr0value\" attr1=\"attr1value\" attr2=\"attr2value\"></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()
    local xml_attribute = xml_node:attribute()

    log_info("xml_attribute:value returned", xml_attribute:value())
else
    log_info("parse xml failed", xml)
end

LuaXmlDocument

root.lua

--[[{
    "name": "Getting the root element from an XML document"
}]]

local xml = "<root><node attr=\"attrvalue\">value</node></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_root = xml_document:root()
    log_info("xmldocument:root returned of class", xml_root._class_name)
else
    log_info("parse xml failed", first)
end

xpathexecute.lua

--[[{
    "name": "Evaluate an XPath expression against an XML document"
}]]

local xml = "<root><node attr=\"attrvalue\">value</node></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_result_set = xml_document:XPathExecute("//root/node")
    log_info("xmldocument:XPathExecute returned of class", xml_result_set._class_name)
else
    log_info("parse xml failed", first)
end

xpathregisterns.lua

--[[{
    "name": "Register a namespace for XPath operations"
}]]

local xml = "<root xmlns=\"http://schemas.autonomy.com/aci/\"><node attr=\"attrvalue\">value</node><node attr=\"attrvalue1\">value1</node></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local values = { xml_document:XPathValues("//root/node/@attr") }

    for i, value in ipairs(values) do
        log_info("xmldocument:XPathValues pre register ns returned", value)
    end

    xml_document:XPathRegisterNs("autn", "http://schemas.autonomy.com/aci/")

    values = { xml_document:XPathValues("//autn:root/autn:node/@attr") }
    for i, value in ipairs(values) do
        log_info("xmldocument:XPathValues post register ns returned", value)
    end

else
    log_info("parse xml failed", first)
end

xpathvalue.lua

--[[{
    "name": "Evaluate an XPath expression to retrieve a single string"
}]]

local xml = "<root><node attr=\"attrvalue\">value</node></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local values = xml_document:XPathValue("//root/node/@attr")
    log_info("xmldocument:XPathValue returned", values)
else
    log_info("parse xml failed", first)
end

xpathvalues.lua

--[[{
    "name": "Evaluate an XPath expression to retrieve multiple strings"
}]]

local xml = "<root><node attr=\"attrvalue\">value</node><node attr=\"attrvalue1\">value2</node></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local values = { xml_document:XPathValues("/root/node/@attr") }

    for i, value in ipairs(values) do
        log_info("xmldocument:XPathValues returned", value)
    end
else
    log_info("parse xml failed", first)
end

LuaXmlNode

attribute.lua

--[[{
    "name": "Getting an XML attribute object"
}]]

local xml = "<root attr=\"attrvalue\">value</root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()

    local xml_attr = xml_node:attribute("attr")
    log_info("xml_node:attribute returned of class", xml_attr._class_name)
else
    log_info("parse xml failed", xml)
end

content.lua

--[[{
    "name": "Getting text content of an node"
}]]

local xml = "<root attr=\"attrvalue\">value</root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()

    local content = xml_node:content()
    log_info("xml_node:content returned", content)
else
    log_info("parse xml failed", xml)
end

firstChild.lua

--[[{
    "name": "Getting the first child node"
}]]

local xml = "<root attr=\"attrvalue\"><child>content1</child><child>content2</child></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()

    local child_node = xml_node:firstChild()
    log_info("xml_node:first_child returned of class", child_node._class_name)
    log_info("xml_node:first_child returned node value", child_node:content())
else
    log_info("parse xml failed", xml)
end

lastChild.lua

--[[{
    "name": "Getting the last child node"
}]]

local xml = "<root attr=\"attrvalue\"><child>content1</child><child>content2</child></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()

    local child_node = xml_node:lastChild()
    log_info("xml_node:last_child returned of class", child_node._class_name)
    log_info("xml_node:last_child returned node value", child_node:content())
else
    log_info("parse xml failed", xml)
end

name.lua

--[[{
    "name": "Getting the name of a node"
}]]

local xml = "<root attr=\"attrvalue\">value</root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()

    local name = xml_node:name()
    log_info("xml_node:name returned", name)
else
    log_info("parse xml failed", xml)
end

next.lua

--[[{
    "name": "Getting the next sibling node"
}]]

local xml = "<root attr=\"attrvalue\"><child>content1</child><child>content2</child></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()

    local child_node = xml_node:firstChild()
    local next_node = child_node:next()

    log_info("xml_node:next returned of class", next_node._class_name)
    log_info("xml_node:next returned node value", next_node:content())
else
    log_info("parse xml failed", xml)
end

nodePath.lua

--[[{
    "name": "Getting the path of a node"
}]]

local xml = "<root attr=\"attrvalue\"><child>content1</child><child>content2</child></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()
    local child_node = xml_node:firstChild()

    log_info("xml_node:node_path returned", child_node:nodePath())
else
    log_info("parse xml failed", xml)
end

parent.lua

--[[{
    "name": "Getting the parent node"
}]]

local xml = "<root attr=\"attrvalue\"><child>content1</child><child>content2</child></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()

    local child_node = xml_node:firstChild()

    local parent_node = child_node:parent()

    log_info("xml_node:parent returned of class", parent_node._class_name)
    log_info("xml_node:parent returned node name", parent_node:name())
else
    log_info("parse xml failed", xml)
end

previous.lua

--[[{
    "name": "Getting the previous sibling node"
}]]

local xml = "<root attr=\"attrvalue\"><child>content1</child><child>content2</child></root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()

    local child_node = xml_node:lastChild()
    local prev_node = child_node:previous()

    log_info("xml_node:previous returned of class", prev_node._class_name)
    log_info("xml_node:previous returned node value", prev_node:content())
else
    log_info("parse xml failed", xml)
end

type.lua

--[[{
    "name": "Getting the type of a node"
}]]

local xml = "<root attr=\"attrvalue\">value</root>"

local xml_document = parse_xml(xml)

if xml_document then
    local xml_node = xml_document:root()

    local node_type = xml_node:type()
    log_info("xml_node:type returned", node_type)
else
    log_info("parse xml failed", xml)
end

LuaXmlNodeSet

at.lua

--[[{
    "name": "Accessing a node from an XML node set"
}]]

local xml =
[===[
<root>
    <node attr="attrvalue">value</node>
    <node attr="attrvalue1">value1</node>
</root>
]===]

local xml_document = parse_xml(xml)

if xml_document then
    local xml_result_set = xml_document:XPathExecute("/root/node")
    local xml_node = xml_result_set:at(0)
    log_info("xmlnodeset:at returned of class", xml_node._class_name)
else
    log_info("parse xml failed", first)
end

size.lua

--[[{
    "name": "Getting the size of an XML node set"
}]]

local xml =
[===[
<root>
    <node attr="attrvalue">value</node>
    <node attr="attrvalue1">value1</node>
</root>
]===]

local xml_document = parse_xml(xml)

if xml_document then
    local xml_result_set = xml_document:XPathExecute("/root/node")
    log_info("xmlnodeset:size", xml_result_set:size())
else
    log_info("parse xml failed", first)
end

classes~miscellaneous

LuaConfig

getEncryptedValue.lua

--[[{
    "name": "Reading an encrypted value from a config"
}]]

local config = LuaConfig:new("[my_section]\nencrypted_parameter="..encrypt("encrypted"))

local param = config:getEncryptedValue("my_section", "encrypted_parameter")

log_info("[my_section] encrypted_parameter read as", param, type(param))

getValue.lua

--[[{
    "name": "Reading a value from a config"
}]]

local config_string = 
[===[
[section]
my_parameter=my_value
my_int_parameter=42
my_bool_parameter=true
]===]

local config = LuaConfig:new(config_string)

local param1 = config:getValue("section", "my_parameter", "default_value")
local param2 = config:getValue("section", "my_missing_parameter", "default_value")
local param3 = config:getValue("section", "my_no_default_parameter")
local param4 = config:getValue("section", "my_int_parameter", 13)
local param5 = config:getValue("section", "my_missing_int_parameter", 13)
local param6 = config:getValue("section", "my_bool_parameter", false)
local param7 = config:getValue("section", "my_missing_bool_parameter", false)

log_info("[section] my_parameter read as", param1, type(param1))
log_info("[section] my_missing_parameter read as", param2, type(param2))
log_info("[section] my_no_default_parameter read as", '"'..param3..'"(quoted)', type(param3))
log_info("[section] my_int_parameter read as", param4, type(param4))
log_info("[section] my_missing_int_parameter read as", param5, type(param5))
log_info("[section] my_bool_parameter read as", param6, type(param6))
log_info("[section] my_missing_bool_parameter read as", param7, type(param7))

getValues_1.lua

--[[{
    "name": "Reading values from a CSV parameter"
}]]

local config_string = 
[===[
[my_section]
csv_parameter=a,bc,def,ghij
]===]

local config = LuaConfig:new(config_string)

local values = { config:getValues("my_section", "csv_parameter") }

log_info("[my_section] csv_parameter read as", table.unpack(values))

getValues_2.lua

--[[{
    "name": "Reading values from numbered parameters"
}]]

local config_string = 
[===[
[my_section]
numbered_parameter0=a
numbered_parameter1=bc
numbered_parameter2=def
numbered_parameter3=ghij
]===]

local config = LuaConfig:new(config_string)

local values = { config:getValues("my_section", "numbered_parameter") }

log_info("[my_section] numbered_parameter read as", table.unpack(values))

new.lua

--[[{
    "name": "Creating a new config object from a string"
}]]

local config_string = 
[===[
[default]
parameter=value
]===]

local config = LuaConfig:new(config_string)

log_info("config returned of class", config._class_name)

LuaRegexMatch

next.lua

--[[{
    "name": "Looping over multiple regex_search results"
}]]

local input_text = "The numbers 6, 28 and 496 are perfect numbers"
local regex_string = "\\d+";

local search_result = regex_search(input_text, regex_string)

while search_result do
    log_info("search result returned of class", search_result._class_name)
    
    search_result = search_result:next()
end

position.lua

--[[{
    "name": "Getting the position and length of a string in a regex_search result"
}]]

local input_text = "The numbers 6, 28 and 496 are perfect numbers"
local regex_string = "\\d+";

local search_result = regex_search(input_text, regex_string)

while search_result do
    log_info("number found at position", search_result:position(),
        "with length", search_result:length())
    
    search_result = search_result:next()
end

str.lua

--[[{
    "name": "Getting the string from a regex match or sub-match"
}]]

local input_text = "The numbers 6, 28 and 496 are perfect numbers"
local regex_string = "\\d+";

local search_result = regex_search(input_text, regex_string)

while search_result do
    log_info("number found with value", search_result:str())
    
    search_result = search_result:next()
end

submatches.lua

--[[{
    "name": "Getting the sub-matches for the current regex match"
}]]

local input_text = "There are queues on the A14, the A34 and on the M25 for 10 miles"
local regex_string = "(A|M)?(\\d+)";

local search_result = regex_search(input_text, regex_string)

local result = 0;
while search_result do
    result = result + 1
    for i=0, search_result:size() - 1 do
        log_info("match", result,
            " sub-match", i,
            " at position", search_result:position(i),
            " with length", search_result:length(i),
            " and value", search_result:str(i))
    end
    
    search_result = search_result:next()
end

functions

config_logs

get_config_1.lua

--[[{
    "name": "Reading a configuration file"
}]]

local config_filename = "my_config.cfg"

local config = get_config(config_filename)

log_info("config returned of class", config._class_name)

get_config_2.lua

--[[{
    "name": "Reading a value from a configuration file"
}]]

local config_filename = "./get_config_1_"..create_uuid()..".cfg"
io.open(config_filename, "w"):write("[my_section]\nmy_parameter=my_value"):close()

local config = get_config(config_filename)

log_info("config returned of class", config._class_name)

local param = config:getValue("my_section", "my_parameter", "default_value")
log_info("[my_section] my_parameter read as", param, type(param))

delete_file(config_filename)

get_log_1.lua

--[[{
    "name": "Writing to a configured log stream"
}]]

local config = get_config("my_config.cfg")

local logstream = get_log_service(config):get_log("LogStream")

logstream:write_line(log_level_debug(), "My debug log message")
logstream:write_line(log_level_full(), "My verbose log message")
logstream:write_line(log_level_normal(), "My informational log message")
logstream:write_line(log_level_warning(), "My warning log message")
logstream:write_line(log_level_error(), "My error log message")
logstream:write_line(log_level_critical(), "My critical log message")
logstream:write_line(log_level_always(), "My log message")

log_info("log returned of class", logstream._class_name)

get_log_2.lua

--[[{
    "name": "Writing to a custom configured log stream"
}]]

local log_filename = "get_log_"..create_uuid()..".log"

local config_string = [===[
[Logging]
LogDirectory=.
0=LogStream

[LogStream]
LogTypeCSVs=lua
LogFile=]===]..log_filename

local config = LuaConfig:new(config_string)

local logstream = get_log_service(config):get_log("lua")

log_info("logstream returned of class", logstream._class_name)

logstream:write_line(log_level_normal(), "My informational log message")

logstream = nil
collectgarbage()
delete_file(log_filename)

get_log_3.lua

--[[{
    "name": "Writing to the NiFI log"
}]]

local logstream = get_log()

logstream:write_line(log_level_debug(), "My trace log message")
logstream:write_line(log_level_full(), "My debug log message")
logstream:write_line(log_level_normal(), "My informational log message")
logstream:write_line(log_level_warning(), "My warning message")
logstream:write_line(log_level_error(), "My error message")
logstream:write_line(log_level_critical(), "My (critical) error message")
logstream:write_line(log_level_always(), "My (informational) log message")

log_trace("My trace log message")
log_debug("My debug log message")
log_info("My informational log message")
log_warn("My warning message")
log_error("My error message")

datetime

convert_date_time.lua

--[[{
    "name": "Convert a date and time between formats"
}]]

local input_date = "04/05/2016 06:34:56 -0600"
local input_formats = "MM/DD/YYYY HH:NN:SS ZZZZZ"
local output_format = "YYYY/MM/DD HH:NN:SS"
local output_gmt = true

local output = convert_date_time(input_date, input_formats, output_format, output_gmt)

log_info("converted date is", output)

extract_date_1.lua

--[[{
    "name": "Extracting a date and time from a string"
}]]

local input_date = "2016/04/04 12:34:56 GMT"
local input_formats = "YYYY/MM/DD HH:NN:SS ZZZ"
local output_format = "EPOCHSECONDS"

local output = extract_date(input_date, input_formats, output_format)

log_info("extracted date is", output)

extract_date_2.lua

--[[{
    "name": "Extracting a date and time from within a string"
}]]

local input_date = "There is a date 22/07 in this text"
local input_formats = "DD/MM/YYYY,DD/MM"
local output_format = "YYYY/MM/DD HH:NN:SS"

local output = extract_date(input_date, input_formats, output_format)

log_info("extracted date is", output)

encryption

encrypt.lua

--[[{
    "name": "Encrypting a string"
}]]

local to_encrypt = "This is quite secret"

local encrypted = encrypt(to_encrypt)

log_info("encrypted text is", encrypted)

encrypt_security_field.lua

--[[{
    "name": "Encrypting an ACL"
}]]

local unencrypted_acl = "0:U:user:G:group:NU::NG:"

local encrypted_acl = encrypt_security_field(unencrypted_acl)

if encrypted_acl then
    log_info("encrypted acl is", encrypted_acl)
else
    log_info("failed to encrypt acl", unencrypted_acl)
end

files

abs_path.lua

--[[{
    "name": "Convert a relative path to absolute"
}]]

local relative_path = "dir/file"

local absolute_path = abs_path(relative_path)

log_info("absolute path is", absolute_path)

copy_file.lua

--[[{
    "name": "Copying a file"
}]]

local path = "./copy_file_"..create_uuid()
local to_path = "./copy_file_to_"..create_uuid()

log_info("copy non existent file returned", copy_file(path, to_path))

file = io.open(path, "w")
if file then
    file:write(path)
    file:close()
end

log_info("copy file returned", copy_file(path, to_path))

delete_file(path)
delete_file(to_path)

create_path.lua

--[[{
    "name": "Creating a directory"
}]]

local path_to_create = "./create_path_"..create_uuid()

local path = create_path(path_to_create)

if path then
    log_info("created path is", path)
    delete_path(path)
else
    log_info("failed to create path", path_to_create)
end

delete_file.lua

--[[{
    "name": "Deleting a file"
}]]

local path = "./delete_file_"..create_uuid()

file = io.open(path, "w")
if file then
    file:write(path)
    file:close()
end

log_info("delete file returned", delete_file(path))

delete_path.lua

--[[{
    "name": "Deleting a directory"
}]]

local path = "./delete_file_"..create_uuid()

log_info("delete non existent path returned", delete_path(path))

path = create_path("./delete_path_"..create_uuid())
if path then
    log_info("delete path returned", delete_path(path))
end

file_set_dates.lua

--[[{
    "name": "Updating created, modified and accessed dates"
}]]

local path = "./file_set_dates_"..create_uuid()

file = io.open(path, "w")
if file then
    file:write(path)
    file:close()
end

local creation_date = nil
local modified_date = "2016/08/05 03:54:18 GMT"
local accessed_date = nil

local result = file_set_dates(
    path,
    creation_date,
    modified_date,
    accessed_date,
    "YYYY/MM/DD HH:NN:SS ZZZ")

log_info("file set dates returned", result)

delete_file(path)

get_cwd.lua

--[[{
    "name": "Getting the current working directory"
}]]

local current_working_dir = get_cwd()

log_info("current working directory is", current_working_dir)

is_dir.lua

--[[{
    "name": "Testing if a path is a directory"
}]]

local this_dir, this_file = script_path()

if is_dir(this_dir) then
    log_info(this_dir.." is a directory")
end

if not is_dir(this_dir..this_file) then
    log_info(this_dir..this_file.." is not a directory")
end

move_file.lua

--[[{
    "name": "Moving a file"
}]]

local path = "./move_file_"..create_uuid()
local to_path = "./move_file_to_"..create_uuid()

log_info("move non existent file returned", move_file(path, to_path))

file = io.open(path, "w")
if file then
    file:write(path)
    file:close()
end

log_info("move file returned", move_file(path, to_path))

delete_file(to_path)

zip

unzip_file.lua

--[[{
    "name": "Unzipping a zip file"
}]]

local zip_filename = "./zip_file.zip"
local unzip_path = "."

local result = unzip_file(zip_filename, unzip_path)

if result then
    log_info(zip_filename, "unzipped to", unzip_path)
end
zip_file_1.lua

--[[{
    "name": "Zipping a single file"
}]]

local file_to_zip = "./zip_file_"..create_uuid()
local overwrite = true

file = io.open(file_to_zip, "w")
if file then
    file:write(file_to_zip)
    file:close()
end

local result = zip_file(file_to_zip, overwrite)

if result then
    log_info(file_to_zip, "zipped to", file_to_zip..".zip")
end

delete_file(file_to_zip)
delete_file(file_to_zip..".zip")
zip_file_2.lua

--[[{
    "name": "Zipping a directory"
}]]

local directory_to_zip = "./dir_to_zip"
local overwrite = true

local result = zip_file(directory_to_zip, overwrite)

if result then
    log_info(directory_to_zip, "zipped to", directory_to_zip..".zip")
end

hashing

hash_file_1.lua

--[[{
    "name": "Calculating the MD5 hash of a file"
}]]

local this_dir, this_file = script_path()

local hash = hash_file(this_dir..this_file, "MD5")

log_info("file md5 hash is", hash)

hash_file_2.lua

--[[{
    "name": "Calculating the SHA1 hash of a file"
}]]

local this_dir, this_file = script_path()

local hash = hash_file(this_dir..this_file, "SHA1")

log_info("file sha1 hash is", hash)

hash_file_3.lua

--[[{
    "name": "Calculating multiple hashes of a file"
}]]

local this_dir, this_file = script_path()

local hash1,hash2 = hash_file(this_dir..this_file, "MD5", "SHA1")

log_info("file md5 sha1 hash is", hash1, hash2)

hash_string_1.lua

--[[{
    "name": "Calculating the MD5 hash of a string"
}]]

local text = "text to hash"

local hash = hash_string(text, "MD5")

log_info("md5 hash is", hash)

hash_string_2.lua

--[[{
    "name": "Calculating the SHA1 hash of a string"
}]]

local hash = hash_string("some text here", "SHA1")

log_info("sha1 hash is", hash)

http

send_aci_action_1.lua

--[[{
    "name": "Send an ACI action"
}]]

local host = "hostname"
local port = 1234
local action = "GetStatus"

local response = send_aci_action(host, port, action)

local response_xml = parse_xml(response)

send_aci_action_2.lua

--[[{
    "name": "Send an ACI action with a parameter list"
}]]

local host = "hostname"
local port = 1234
local action = "QueueInfo"
local params = { QueueName="Fetch", QueueAction="GetStatus" }

local response = send_aci_action(host, port, action, params)

local response_xml = parse_xml(response)

send_aci_command.lua

--[[{
    "name": "Send an ACI action using an encoded query string"
}]]

local host = "hostname"
local port = 1234
local action = "action=QueueInfo&QueueName=Fetch&QueueAction=GetStatus"

local response = send_aci_command(host, port, action)

local response_xml = parse_xml(response)

send_and_wait_for_async_action.lua

--[[{
    "name": "Send an asynchronous ACI action and wait for a result"
}]]

local host = "hostname"
local port = 1234
local action = "Fetch"
local params = { FetchAction="Identifiers", ParentIdentifier="ROOT" }

local response = send_and_wait_for_async_aci_action(host, port, action, params)

local response_xml = parse_xml(response)

send_http_request.lua

--[[{
    "name": "Send an HTTP request"
}]]

local serverPort = 7000

local response = send_http_request({
--  url = "http://localhost:7000/?action=getstatus",
    method = "GET",
    site = "localhost",
    port = serverPort,
    uri = "/",
    params = { action = "getstatus" }
})

log_info("Response:", response)

miscellaneous

create_uuid.lua

--[[{
    "name": "Create a unique identifier"
}]]

local uuid = create_uuid()

log_info("uuid is", uuid)

gobble_whitespace.lua

--[[{
    "name": "Strip consecutive whitespace from a string"
}]]

local gobbled = gobble_whitespace("  text     with        whitespace      ")

log_info("gobble whitespace result is", gobbled)

sleep.lua

--[[{
    "name": "Sleep for a number of milliseconds"
}]]

-- ten seconds
log_info(10*1000)

parsing

json

parse_json_1.lua

--[[{
    "name": "JSON value from a stringified JSON object"
}]]

local json = '{"attr":"attrvalue","obj":{"attr1":true,"attr2":2}}'

local json_value = parse_json(json)

if json_value then
    log_info("parsed json returned of class", json_value._class_name)
else
    log_info("parse json failed")
end
parse_json_2.lua

--[[{
    "name": "JSON value from a stringified JSON array"
}]]

local json = '["attrvalue",true,2]'

local json_value = parse_json(json)

if json_value then
    log_info("parsed json returned of class", json_value._class_name)
else
    log_info("parse json failed")
end
parse_json_3.lua

--[[{
    "name": "Parsing a JSON object"
}]]

local json = '{"attr":"attrvalue","obj":{"attr1":true,"attr2":2}}'

local json_object = parse_json_object(json)

if json_object then
    log_info("parsed json returned of class", json_object._class_name)
else
    log_info("parse json failed")
end
parse_json_4.lua

--[[{
    "name": "Parsing a JSON array"
}]]

local json = '["attrvalue",true,2]'

local json_array = parse_json_array(json)

if json_array then
    log_info("parsed json returned of class", json_array._class_name)
else
    log_info("parse json failed")
end

single_csv

parse_csv_1.lua

--[[{
    "name": "Parsing a CSV with known number of values"
}]]

local first,second = parse_csv("simple csv, really")

log_info("first csv value is", first)
log_info("second csv value is", second)
parse_csv_2.lua

--[[{
    "name": "Parsing a CSV with escaped commas and quotes"
}]]

local first,second,third = parse_csv("\"another csv\", \" with (\\\") quotes\", and (\\,) commas")

log_info("first csv value is", first)
log_info("second csv value is", second)
log_info("third csv value is", third)
parse_csv_3.lua

--[[{
    "name": "Parsing a CSV keeping quotes"
}]]

local first,second = parse_csv("\" more csv \", \"keeping (\") quotes\"", false)

log_info("first csv value is", first)
log_info("second csv value is", second)
parse_csv_4.lua

--[[{
    "name": "Parsing a CSV to a list"
}]]

local many = { parse_csv("list, of, words, separated, by , comma") }

for i,v in ipairs(many) do
    log_info("csv value", i, "is", v)
end
parse_csv_5.lua

--[[{
    "name": "Parsing a CSV using a different separator"
}]]

local many = { parse_csv("with! different! separator", "!") }

for i,v in ipairs(many) do
    log_info("csv value", i, "is", v)
end
parse_csv_6.lua

--[[{
    "name": "Parsing a CSV with a different separator and keeping quotes"
}]]

local many = { parse_csv("\" keeping quotes \"! with different ! separator", "!", false) }

for i,v in ipairs(many) do
    log_info("csv value", i, "is", v)
end

xml

parse_xml.lua

--[[{
    "name": "Parsing XML"
}]]

local xml = "<root><node attr=\"attrvalue\">value</node></root>"

local xml_document = parse_xml(xml)

if xml_document then
    log_info("parsed xml returned of class", xml_document._class_name)
else
    log_info("parse xml failed")
end

regex

regex_match_1.lua

--[[{
    "name": "Matching a string and extracting sub-matches"
}]]

local input_text = "abrAcadAbra"
local regex_string = "(a.r)((?:(?i)a.(?-i))*ra)"

local results = { regex_match(input_text, regex_string) }

for i,v in ipairs(results) do
    log_info("regex match result", i, "is", v)
end

regex_match_2.lua

--[[{
    "name": "Testing whether a string matches"
}]]

local input_text = "Rhythm"
local contains_vowel_regex = ".*?[aeiou].*"
local consonants_only_regex = "[b-df-hj-np-tv-z]*"

if not regex_match(input_text, contains_vowel_regex, false) then
    log_info(input_text, "does not contain any vowels")
end

if regex_match(input_text, consonants_only_regex, false) then
    log_info(input_text, "contains only consonants")
end

regex_replace_all_1.lua

--[[{
    "name": "Replacing matches in a string"
}]]

local input_text = "brcdbr"
local regex_string = "([bcd]|$)"
local replacement_text = "a\\1"

local result = regex_replace_all(input_text, regex_string, replacement_text)

log_info("text with replacements is", result)

regex_replace_all_2.lua

--[[{
    "name": "Replacing matches in a string with UTF8 whitespace"
}]]

local input_text = "This is a few URLs: https://qwer.adsf/zxcv  https://wert.sdfg/xcvb https://erty.dfgh/cvbn"

local utf8Whitespace = "\\x20" --SPACE
    .."|\\xc2\\xa0"      --NO-BREAK-SPACE
    .."|\\xe1\\x9a\\x80" --OGHAM SPACE MARK
    .."|\\xe2\\xa0\\x8e" --MONGOLIAN VOWEL SEPARATOR
    .."|\\xe2\\x80\\x80" --EN QUAD
    .."|\\xe2\\x80\\x81" --EM QUAD
    .."|\\xe2\\x80\\x82" --EN SPACE
    .."|\\xe2\\x80\\x83" --EM SPACE
    .."|\\xe2\\x80\\x84" --THREE-PER-EM SPACE
    .."|\\xe2\\x80\\x85" --FOUR-PER-EM SPACE
    .."|\\xe2\\x80\\x86" --SIX-PER-EM SPACE
    .."|\\xe2\\x80\\x87" --FIGURE SPAC
    .."|\\xe2\\x80\\x88" --PUNCTUATION SPACE
    .."|\\xe2\\x80\\x89" --THIN SPACE
    .."|\\xe2\\x80\\x8a" --HAIR SPACE
    .."|\\xe2\\x80\\x8b" --ZERO WIDTH SPACE
    .."|\\xe2\\x80\\xaf" --NARROW NO-BREAK SPACE
    .."|\\xe2\\x81\\x9f" --MEDIUM MATHEMATICAL SPACE
    .."|\\xe3\\x80\\x80" --IDEOGRAPHIC SPACE
    .."|\\xef\\xbb\\xbf" --ZERO WIDTH NO-BREAK SPACE
local whitespace = "\\t|\\r|\\n|\\f"
local anyWhitespace = utf8Whitespace .. "|" .. whitespace
local untilNextWhiteSpace = "(?:.*?)?(?=" .. anyWhitespace .. "|$)"

local result = regex_replace_all(input_text, "http(s)?:\\/\\/t\\.co\\/" .. untilNextWhiteSpace, "")

log_info("text with replacements is", result)

regex_search.lua

--[[{
    "name": "Searching within a string"
}]]

local input_text = "The words abstemious, caesious and facetious contain all vowels in order"
local regex_string = string.gsub("XaXeXiXoXuX", "X", "([b-df-hj-np-tv-z]*)")

local search_result = regex_search(input_text, regex_string, false)

while search_result do

    log_info("search result is from character", search_result:position(), "of length", search_result:length(), "with text", search_result:str())

    for i=1,search_result:size()-1 do
        log_info("  submatch from character", search_result:position(i), "of length", search_result:length(i), "with text", search_result:str(i))
    end

    search_result = search_result:next()
end

script_path

script_path_1.lua

--[[{
    "name": "Getting the script directory and filename"
}]]

local script_directory, script_filename = script_path()

log_info("script directory is", script_directory)
log_info("script filename is", script_filename)

script_path_2.lua

--[[{
    "name": "Construct a path relative to this script directory"
}]]

local other_script_relative_path = "my_path/my_script.lua"

local other_script_absolute_path = script_path()..other_script_relative_path

log_info("other script path is", other_script_absolute_path)

script_path_3.lua

--[[{
    "name": "Alternative method using debug.getinfo"
}]]

local script_path_alternative = function()
    local ds = debug.getinfo(1, "S")
    if ds then
        ds = ds.source
        if ds and ds:sub(1,1) == "@" then
            ds = abs_path(ds:sub(2))
            return ds:match("^(.+[\\\\/])([^\\\\/]+)$")
        end
    end
end

local script_directory, script_filename = script_path()
local script_directory_a, script_filename_a = script_path_alternative()

if script_directory == script_directory_a then
    log_info("script directory", script_directory, "matches alternative", script_directory_a)
end

if script_filename == script_filename_a then
    log_info("script filename", script_filename, "matches alternative", script_filename_a)
end

string_encoding

base64_decode.lua

--[[{
    "name": "Decoding a base64 encoded string"
}]]

local to_decode = "VGhpcyB3YXMgYmFzZTY0IGVuY29kZWQ="

local decoded = base64_decode(to_decode)

log_info("base64 decoded text is", decoded)

base64_encode.lua

--[[{
    "name": "Base64 encoding a string"
}]]

local to_encode = "Let's base64 encode"

local encoded = base64_encode(to_encode)

log_info("base64 encoded text is", encoded)

convert_encoding_1.lua

--[[{
    "name": "Converting strings between character encodings"
}]]

local utf8_string = "\xE6\x88\x91\xE7\x9A\x84\xE5\x90\x8D\xE5\xAD\x97\xE6\x98\xAF\xE5\xB0\x8F\xE6\x98\x8E\xE3\x80\x82"
local ucs2_string = "\x11\x62\x84\x76\x0D\x54\x57\x5B\x2F\x66\x0F\x5C\x0E\x66\x02\x30"

local ucs2 = convert_encoding(utf8_string, "UCS2")

log_info("converted string is", string.format(string.rep("%02X", ucs2:len()), ucs2:byte(1, ucs2:len())))
if ucs2_string == ucs2 then
    log_info("converted string matches expected")
end

local utf8 = convert_encoding(ucs2, "UTF8", nil, "UCS2")

log_info("string converted back is", string.format(string.rep("%02X", utf8:len()), utf8:byte(1, utf8:len())))
if utf8_string == utf8 then
    log_info("string converted back to original")
end

convert_encoding_2.lua

--[[{
    "name": "Converting strings between character encodings using a conversion table"
}]]

local unicode_table_directory = "./convtables"

local utf8_string = "\xE6\x88\x91\xE7\x9A\x84\xE5\x90\x8D\xE5\xAD\x97\xE6\x98\xAF\xE5\xB0\x8F\xE6\x98\x8E\xE3\x80\x82"

local big5 = convert_encoding(utf8_string, "CHINESETRADITIONAL", unicode_table_directory)

log_info("converted string is", string.format(string.rep("%02X", big5:len()), big5:byte(1, big5:len())))

url_escape.lua

--[[{
    "name": "URL escaping a string"
}]]

local to_escape = "This will be 100% url escaped"

local escaped = url_escape(to_escape)

log_info("url escaped text is", escaped)

url_unescape.lua

--[[{
    "name": "Unescaping a URL encoded string"
}]]

local to_unescape = "%55%52%4C%20%65%73%63%61%70%69%6E%67%20%69%73%20%2566%2575%256E!"

local unescaped = url_unescape(to_unescape)

log_info("url unescaped text is", unescaped)

xml_encode.lua

--[[{
    "name": "XML encoding a string"
}]]

local to_encode = "some <text> to &encode"

local encoded = xml_encode(to_encode)

log_info("xml encoded text is", encoded)

utilities

acl_string.lua

--[[{
    "name": "Module: acl_string"
}]]

local transform_string = require("utilities_transform_string")
local functional = require("utilities_functional")

local acl_string = {}

-- Encrypt an ACL string using a regex to match the encryptable components.
acl_string.encrypt_with_regex
    = transform_string.by_regex_fn(transform_string.comma_separated_fn(encrypt))

-- Constant strings defining standard ACL components.
acl_string.users_component = "U"
acl_string.groups_component = "G"
acl_string.no_users_component = "NU"
acl_string.no_groups_component = "NG"

-- Get the standard ACL component regex for use with acl_string.encrypt_with_regex.
function acl_string.component_regex()
    return "(?:^|:)(?:U|G|NU|NG|S|RG|R1G):([^:]*)"
end

-- Returns a regex to match a specific single ACL component.
function acl_string.single_component_regex(component_string)
    return "(?:^|:)(?:"..component_string:gsub("[^%w]", "\\%0").."):([^:]*)"
end

-- Encrypt an ACL using the standard ACL format
function acl_string.encrypt(acl)
    return acl_string.encrypt_with_regex(acl, acl_string.component_regex())
end

-- Set the names in a component of an ACL.  No encryption is performed.
function acl_string.set_names(acl, component_string, ...)
    local names = table.concat({...}, ",")
    return transform_string.by_regex(
        acl,
        acl_string.single_component_regex(component_string),
        function(input) return names end)
end

-- Encrypt and set the names in a component of an ACL.
function acl_string.set_and_encrypt_names(acl, component_string, ...)
    return acl_string.set_names(acl, component_string, functional.map(encrypt, ...))
end

-- Add names to a component of an ACL.  No encryption is performed.
function acl_string.add_names(acl, component_string, ...)
    local names = table.concat({...}, ",")
    return transform_string.by_regex(
        acl,
        acl_string.single_component_regex(component_string),
        function(input)
            if input == "" then return names end
            return input .. "," .. names
        end)
end

-- Encrypt and add names to a component of an ACL.
function acl_string.add_and_encrypt_names(acl, component_string, ...)
    return acl_string.add_names(acl, component_string, functional.map(encrypt, ...))
end

return acl_string

document_extensions.lua

--[[{
    "name": "Extension functions for LuaDocument class"
}]]

-- Return the LuaField for the AUTN_IDENTIFIER field of a document.
function LuaDocument.get_identifier_field(document)
    return document:getFields("AUTN_IDENTIFIER"),nil
end

-- Return the identifier string from the AUTN_IDENTIFIER field of a document.
function LuaDocument.get_identifier(document)
    local identifier_field = document:get_identifier_field()
    if identifier_field then
        return identifier_field:value()
    end
end

-- Return the sub file indices table from the AUTN_IDENTIFIER field of a document.
function LuaDocument.get_sub_file_indices(document)
    local sub_file_indices_field = document:getFields("SubFileIndexCSV"),nil
    if sub_file_indices_field then
        return { parse_csv(sub_file_indices_field:value()) }
    end
end

-- Return the LuaField for the AUTONOMYMETADATA (ACL) field of a document.
function LuaDocument.get_acl_field(document)
    return document:getFields("AUTONOMYMETADATA"),nil
end

-- Return the ACL string from the AUTONOMYMETADATA (ACL) field of a document.
function LuaDocument.get_acl(document)
    local acl_field = document:get_acl_field()
    if acl_field then
        return acl_field:value()
    end
end

-- Return true if the value of a field of a document matches an expression
function LuaDocument.field_matches(document, fieldname, expression)
    local field_values = document:getFieldValues(fieldname)
    for i, value in ipairs({field_values}) do
        if value == regex_match(value, expression) then
            return true
        end
    end
    return false
end

-- Return true if the value of a field of a document is within a given range
function LuaDocument.field_value_between(document, fieldname, lower, upper)
    local field_values = document:getFieldValues(fieldname)
    for i, value in ipairs({field_values}) do
        local num_value = tonumber(value)
        if lower <= num_value and num_value <= upper then
            return true
        end
    end
    return false
end

-- Returns true if the document content does not exist or is empty
function LuaDocument.is_content_empty_or_whitespace(document)
    return ( string.find(document:getContent(), "%S") == nil )
end

-- Splits a field based on a given pattern and stores the split values into new fields
function LuaDocument.split_field(document, fieldName, pattern, newFieldName)
	local fpat = "(.-)" .. pattern

	for i, str in ipairs({document:getFieldValues(fieldName)}) do
		local last_end = 1
		local s, e, cap = str:find(fpat, 1)
		while s do
			if s ~= 1 or cap ~= "" then
				document:addField(newFieldName, cap)
			end
			last_end = e + 1
			s, e, cap = str:find(fpat, last_end)
		end
		if last_end <= #str then
			cap = str:sub(last_end)
			document:addField(newFieldName, cap)
		end
	end
end

document_identifier.lua

--[[{
    "name": "Module: document_identifier"
}]]

local document_identifier = {}

--[[
Split an identifier string into the base64 string component
and the sub file indices string component.
--]]
function document_identifier.parts(identifier_string)
    return identifier_string:match("^([%w/+]+=*)|([%d.]+)$")   
end

-- Extract the sub file indices from an identifier string as a table of indices
function document_identifier.sub_file_indices(identifier_string)
    local base64part, indices = document_identifier.parts(identifier_string)
    if indices then
        return { parse_csv(indices, ".") }
    end
end

-- Append sub file indices as a table of indices to an identifier string
function document_identifier.append_sub_file_indices(identifier_string, sub_file_indices)
    local idstr = identifier_string
    if not document_identifier.sub_file_indices(identifier_string) and sub_file_indices then
        local indices = table.concat(sub_file_indices, ".")
        if indices ~= "" then
            idstr = idstr.."|"..indices
        end
    end
    return idstr
end

-- Extract the XML data from an identifier string and return a LuaXmlDocument object.
function document_identifier.xml(identifier_string)
    local idstr = document_identifier.parts(identifier_string)
    if idstr then
        local xml = base64_decode(idstr)
        if xml then
            return parse_xml(xml)
        end
    end
end

return document_identifier

functional.lua

--[[{
    "name": "Module: functional"
}]]

local functional = {}

--[[
Bind arguments to a function and return the new function.
The position of the bound arguments is specified as either a count from the
first argument to the first argument to bind, or a negative count from the last
argument to the last argument to bind.  A zero position is interpreted as
appending the arguments at the end.

All the examples below are equivalent to calling fn("a", "b", "c", "d", "e")

-- bind arguments at end
functional.bind(fn, 0, "d", "e")("a", "b", "c")

-- bind 1st and 2nd arguments
functional.bind(fn, 1, "a", "b")("c", "d", "e")

-- bind 3rd and 4th arguments
functional.bind(fn, 3, "c", "d")("a", "b", "e")

-- negative position indicates position relative to end of total arguments
-- the position is the last argument to bind
-- (-1) with a single bind argument will just bind the last argument 
-- bind last two arguments
functional.bind(fn, -1, "d", "e")("a", "b", "c")

-- bind two arguments before the last two arguments
functional.bind(fn, -3, "b", "c")("a", "d", "e")
--]]
function functional.bind(fn, bind_from_position, ...)
    local bind_args = { n = select("#", ...); ... }
    return function(...)
        local args = { n = select("#", ...); ... }
        local fn_args = {}
        if bind_from_position < 0 then
            bind_from_position = args.n + 2 + bind_from_position
            if bind_from_position <= 0 then
                bind_from_position = 1
            end
        end
        if bind_from_position == 0 then
            bind_from_position = args.n + 1
        end
        for i=1, bind_from_position - 1, 1 do
            fn_args[i] = args[i]
        end
        for i=1, bind_args.n, 1 do
            fn_args[bind_from_position - 1 + i] = bind_args[i]
        end
        for i=bind_from_position, args.n, 1 do
            fn_args[bind_args.n + i] = args[i]
        end
        return fn(table.unpack(fn_args))
    end
end

-- Return the results of applying a transform function to each remaining argument.
function functional.map(transform_function, ...)
    local args = { n = select("#", ...); ... }
    local result = {}
    for i=1, args.n, 1 do
        result[i] = transform_function(args[i])
    end
    return table.unpack(result)
end

--[[
Return the resulting table after applying a transform function to the elements
of a table.  The transform function takes the value and key (in that order) as
arguments, and returns a new value and optionally a new key.
--]]
function functional.table_map(transform_v_k_function, t)
    local result = {}
    for k,v in pairs(t) do
        local newv, newk = transform_v_k_function(v,k)
        if newk then
            result[newk] = newv
        else
            result[k] = newv
        end
    end
    return result
end

--[[
Returns a single result from combining the input values using a fold function.
The fold_function takes the current result value and the next input value as
arguments, and returns a new result value.  The result value is initially
assigned the provided initial_value.
--]]
function functional.fold(fold_function, initial_value, ...)
    local args = { n = select("#", ...); ... }
    local result = initial_value
    for i=1, args.n, 1 do
        result = fold_function(result, args[i])
    end
    return result
end

return functional

graph_import.lua

--[[{
    "name": "Module: graph_import",
    "info": "Utility module for importing entities into a graph"
}]]

-- Usage example:
--
--   local graph = require("graph_import")
--
--   local importer = graph.new()
--
--   -- Set any option overrides here for example
--   --   importer.setAuthorizeOption("authServerUrl", "https://localhost:8010")
--   -- see importermeta.httpParams, importermeta.authorizeParams and importermeta.graphParams below
--   
--   importer.authorize("eurus_super_user", "eurus_super_user")
--   
--   importer.entityFindOrFail("global",
--       {"typeId==TeamEntity and properties:TeamEntity:title=contains=Global"})
--
--   importer.entityFindOrCreate("813175687",
--       "AccountEntity",
--       {accountId="813175687", userName="MissPatriot89", displayName="Michelle"},
--       {"accountId"})
--
--   importer.entityFindOrCreate("1323730225067339784",
--       "AccountEntity",
--       {accountId="1323730225067339784", userName="WhiteHouse", displayName="The White House"},
--       {"accountId"})
--
--   importer.entityCreate("1594905397701246976",
--       "SocialPostEntity",
--       {text="@WhiteHouse Go away already",
--           geotag=LuaJsonObject:new({
--               type="Point",
--               coordinates=LuaJsonArray:new(-98.5, 39.76)})})
--
--   importer.entityLink("1594905397701246976", "813175687", "PostedBy")
--   importer.entityLink("1594905397701246976", "1323730225067339784", "ResponseTo")
--   importer.entityLink("1594905397701246976", "1323730225067339784", "Mentions")
--
--   importer.entityAccess({"global"})
--   
--   local result = importer.execute()

local graph_import = {}

function graph_import.new()
    
    local importer = {}
    local importermeta = {}

    
	importermeta.httpParams = {
        proxyHost="",
        proxyPort=""
    }
    
    importermeta.getHttpConfig = function()
        local cfg = "[http]\n"
        for k,v in pairs(importermeta.httpParams) do
         	cfg = cfg..k.."="..v.."\n"
        end
    	return LuaConfig:new(cfg)
    end

	importermeta.authorizeParams = {
        authServerUrl="http://localhost:8010",
        authServerPath="/realms/lema/protocol/openid-connect/token",
        clientId="lema_api",
        clientSecret="d0e76ad7-7d6b-4d86-be3a-5dfe715dbf87"
    }
    
    importermeta.authorization = ""

	importermeta.graphParams = {
        graphServerUrl="http://localhost:8060",
        graphServerPath="/entities/graph",
        tenantId="tenant_id"
    }
    
    importermeta.entitydefs = {}
    importermeta.linkdefs = {}
    importermeta.accessdefs = {}
    
    
    
    importer.setHttpOption = function(k,v)
        importermeta.httpParams[k] = v
    end

    importer.setAuthorizeOption = function(k,v)
        importermeta.authorizeParams[k] = v
    end

    importer.authorize = function(u,p)
        local request = LuaHttpRequest:new(importermeta.getHttpConfig(), "http")

        request:set_method("POST")
        request:set_url(importermeta.authorizeParams.authServerUrl..importermeta.authorizeParams.authServerPath)
        request:set_headers({
                ["Content-Type"]="application/x-www-form-urlencoded",
                ["Accept"]="application/json"
            })
        request:set_body("grant_type=password"
            .."&client_id="..url_escape(importermeta.authorizeParams.clientId)
            .."&client_secret="..url_escape(importermeta.authorizeParams.clientSecret)
            .."&username="..url_escape(u)
            .."&password="..url_escape(p))

        local response = request:send()

        if 200 ~= response:get_http_code() then
            error("Authorize error: HTTP"..tostring(response:get_http_code()))
        end

        importermeta.authorization = "Bearer "..parse_json_object(response:get_body()):lookup("access_token"):value()
    end
    
    

    importer.setGraphOption = function(k,v)
        importermeta.graphParams[k] = v
    end
    
	-- Example: importer.entityFindOrFail("global", {"typeId==TeamEntity and properties:TeamEntity:title=contains=Global"})
    importer.entityFindOrFail = function(label, findFilterSteps)
        table.insert(importermeta.entitydefs, {
            label=label,
            data=LuaJsonObject:new({
                importType = "FindOrFail",
                find = LuaJsonObject:new({
                    findFilterSteps = LuaJsonArray:new(table.unpack(findFilterSteps))
                })
            })
        })
    end

    -- Example: importer.entityCreate("1594905397701246976",
    --              "SocialPostEntity",
    --				{text="@WhiteHouse Go away already", geotag=LuaJsonObject:new(...)})
    importer.entityCreate = function(label, typeId, properties, accessibleByLabels)

        local create = LuaJsonObject:new({
            typeId = typeId,
            properties = LuaJsonObject:new((properties ~= nil) and properties or {})
        })

        if AccessibleByLabels ~= nil then
            create:assign("access", LuaJsonObject:new({
                accessibleByLabels = LuaJsonArray:new(table.unpack(accessibleByLabels))
            }))
        end

        table.insert(importermeta.entitydefs, {
            label=label,
            data=LuaJsonObject:new({
                importType = "Create",
                create = create
            })
        })

    end

    -- Example: importer.entityFindOrCreate("1323730225067339784",
    --              "AccountEntity",
    --              {accountId="1323730225067339784", userName="WhiteHouse", displayName="The White House"}
    --			    {"accountId"})
    importer.entityFindOrCreate = function(label, typeId, properties, matchProperties, accessibleByLabels)

        local create = LuaJsonObject:new({
            typeId = typeId,
            properties = LuaJsonObject:new((properties ~= nil) and properties or {})
        })

        if AccessibleByLabels ~= nil then
            create:assign("access", LuaJsonObject:new({
                accessibleByLabels = LuaJsonArray:new(table.unpack(accessibleByLabels))
            }))
        end

        table.insert(importermeta.entitydefs, {
            label=label,
            data=LuaJsonObject:new({
                importType = "FindOrCreate",
                find = LuaJsonObject:new({
                    matchProperties = LuaJsonArray:new(table.unpack(matchProperties))
                }),
                create = create
            })
        })

    end

    -- Example: importer.entityLink("1594905397701246976", "1323730225067339784", "Mentions")
    importer.entityLink = function(sourceLabel, targetLabel, typeId, properties)

        table.insert(importermeta.linkdefs, {
            sourceEntityLabel = sourceLabel,
            targetEntityLabel = targetLabel,
            typeId = typeId,
            properties = LuaJsonObject:new((properties ~= nil) and properties or {})
        })

    end

    -- Example: importer.entityAccess({"global"})
    importer.entityAccess = function(accessibleByLabels)

        table.insert(importermeta.accessdefs, {
            accessibleByLabels = LuaJsonArray:new(table.unpack(accessibleByLabels))
        })

    end
    
    
    
    -- Returns table mapping entity labels to entity IDs
    importer.execute = function()
        
        local entities = LuaJsonObject:new()
        local links = LuaJsonArray:new()
        local body = LuaJsonObject:new({ entities = entities, links = links })
        
        for i,v in ipairs(importermeta.entitydefs) do
            if entities:exists(v.label) then
                error("Entity "..v.label.. " already exists in parameters")
            end
            entities:assign(v.label, v.data)
        end
        
        for i,v in ipairs(importermeta.linkdefs) do
            if not entities:exists(v.sourceEntityLabel) then
                error("Link entity "..v.sourceEntityLabel.. " does not exist in parameters")
            end
            if not entities:exists(v.targetEntityLabel) then
                error("Link entity "..v.targetEntityLabel.. " does not exist in parameters")
            end
            links:append(LuaJsonObject:new(v))
        end
        
        for i,v in ipairs(importermeta.accessdefs) do
            local access = body:lookup("access")
            if access ~= nil then
                local accessibleByLabels = access:lookup("accessibleByLabels"):array()
                for i,vv in v.accessibleByLabels:array():ipairs() do
                    accessibleByLabels:append(vv)
                end
            else
                body:assign("access", LuaJsonObject:new(v))
            end
        end
        
        importermeta.entitydefs = {}
        importermeta.linkdefs = {}
        importermeta.accessdefs = {}

        local request = LuaHttpRequest:new(importermeta.getHttpConfig(), "http")

        request:set_method("POST")
        request:set_url(importermeta.graphParams.graphServerUrl..importermeta.graphParams.graphServerPath)
        request:set_headers({
                ["Authorization"]=importermeta.authorization,
                ["Content-Type"]="application/json",
                ["Isol-Tenant-Id"]=importermeta.graphParams.tenantId,
                ["Accept"]="application/json"
            })
        request:set_body(body:string())

        local response = request:send()

        if 201 ~= response:get_http_code() then
            error("Execute error: HTTP"..tostring(response:get_http_code()))
        end

        local result = {}
        for k, v in parse_json_object(response:get_body()):pairs() do
            result[k] = v:value()
        end
        return result
        
    end
    
    
    
    setmetatable(importer, importermeta)
    return importer
    
end

return graph_import

table_operations.lua

--[[{
    "name": "Module: table_operations"
}]]

local table_operations = {}

--[[
Alternative to the built-in pairs function that will return ordered by the key,
instead of an arbitrary ordering.

for k,v in table_operations.ordered_pairs(t) do
    ...
end
--]]
function table_operations.ordered_pairs(t)
    local key_by_index = {}
    for k in pairs(t) do
        table.insert(key_by_index, k)
    end
    table.sort(key_by_index)
    local index_by_key = {}
    for i,k in ipairs(key_by_index) do
        index_by_key[k] = i
    end
    local ordered_next = function(t, k)
            local key = nil
            if k == nil then
                key = key_by_index[1]
            else
                local i = index_by_key[k]
                if i then
                    key = key_by_index[i+1]
                end
            end
            if key then
                return key, t[key]
            end
            return
        end
    return ordered_next, t, nil
end

--[[
Convert table into an approximate JSON representation of the table.
This lacks full string escaping, and non-printable types will be shown
using the default tostring output.
--]]
function table_operations.to_json(t)
    local result = "{"
    local first = true
    for k,v in table_operations.ordered_pairs(t) do
        local vt = type(v)
        local vjson = ""
        if vt == "string" then
            vjson = '"'..v:gsub('["\\\\]', "\\%0"):gsub("%c", " ")..'"'
        elseif vt == "table" then
            vjson = table_operations.to_json(v)
        elseif vt == "number" or vt == "boolean" then
            vjson = tostring(v)
        else
            vjson = '"'..tostring(v)..'"'
        end
        local append_value = '"'..k:gsub('["\\\\]', '\\%0'):gsub("%c", " ")..'":'..vjson
        if first then
            result = result..append_value
            first = false
        else
            result = result..","..append_value
        end
    end
    return result.."}"
end

return table_operations

transform_string.lua

--[[{
    "name": "Module: transform_string"
}]]

local functional = require("utilities_functional")

local transform_string = {}

--[[
Perform a transformation on the elements of a char separated list.
Specify the input string, the character to use as a separator (the first char of
the provided string is used), and a transform function taking an string
and returning the transformed string.
--]]
function transform_string.char_separated(input_csv, char_separator, transform_function)
    local c = char_separator:sub(1,1)
    if c == "" then
        return input_csv
    end
    local result = ""
    local to_transform = { parse_csv(input_csv, c) }
    for i,v in ipairs(to_transform) do
        if i > 1 then
            result = result .. c
        end
        result = result .. transform_function(v)
    end
    return result
end

--[[
Returns a function that calls transform_string.char_separated with last arguments
bound to the arguments provided
--]]
function transform_string.char_separated_fn(...)
    return functional.bind(transform_string.char_separated, -1, ...)
end

-- Version of transform_string.char_separated using a comma separator.
function transform_string.comma_separated(input_csv, transform_function)
    return transform_string.char_separated(input_csv, ",", transform_function)
end

--[[
Returns a function that calls transform_string.comma_separated with last argument
bound to the argument provided
--]]
function transform_string.comma_separated_fn(transform_function)
    return functional.bind(transform_string.comma_separated, 2, transform_function)
end

-- Transform a string using a regular expression to match substrings to be transformed.
function transform_string.by_regex(input_string, regex_string, transform_function)
    local result = ""
    local pos = 1
    local search_result = regex_search(input_string, regex_string)
    while search_result do
        if search_result:position() >= pos then
            for i = 1, search_result:size() - 1 do
                result = result
                    .. input_string:sub(pos, search_result:position(i) - 1)
                    .. transform_function(search_result:str(i))
                pos = search_result:position(i) + search_result:length(i)
            end
         end
        search_result = search_result:next()
    end
    return result .. input_string:sub(pos)
end

--[[
Returns a function that calls transform_string.by_regex with last arguments
bound to the arguments provided
--]]
function transform_string.by_regex_fn(...)
    return functional.bind(transform_string.by_regex, -1, ...)
end

return transform_string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment