Groovy

Groovy is a scripting language that is very close to Java. The syntax is almost identical to the syntax of Java, with some enhancements. For example, in Groovy it is possible to make a typeless declaration of variables if you want to. Intrexx uses Groovy mainly for controlling processes, performing complex calculations, as well as complex queries. Due to the similarity to Java, it is possible in most cases to copy scripts from the diverse Java world and reuse them in Groovy. Here, too, you can integrate your own Java classes. The API offers several ways to access important Intrexx functionalities and objects.

Click here for general information about scripting in Intrexx.

Intrexx Standard Library

In the Groovy script editor, you can access the Intrexx Standard Library on the "libraries" tab. If you select an entry in the library, you can access these buttons at the bottom right of this area:

Show description

Shows the description of the currently selected function with an example script.

Open link

Links to the corresponding page that provides more information. The page that opens also shows the classes, interfaces, methods or properties that the currently selected function can be used for. This opens the exact page with the classes, interfaces, methods or properties that you can use for the currently selected function.

Application structure

Application property from data record object

Reads application properties from a data record object. Replace "myMethod()" in the example script with the desired method.

Example

def appInfoValue = g_record.applicationInfo.getGuid()

Returns the GUID of the application that the record belongs to.

Snippet

def appInfoValue = g_record.applicationInfo.myMethod()

Class AbstractGroovyRecord

Data group property from data record object

Reads data group properties from a data record object. Replace "myMethod()" in the example script with the desired method.

Example

def dgInfoValue = g_record.dataGroupInfo.getGuid()

Returns the GUID of the data group that the record belongs to.

Snippet

def dgInfoValue = g_record.dataGroupInfo.myMethod()

Class AbstractGroovyRecord

Interface DataGroupInfo

Application info

Information about the application with the stated GUID. Replace "myMethod()" in the example script with the desired method.

Example

def appPropValue = app?.getGuid()

Returns the GUID of the application.

Snippet

def app = g_rtCache.applications["<application GUID>"]
def appPropValue = app?.myMethod()

Interface ApplicationInfo

Control info

Returns information about the control with the stated GUID. Replace "myMethod()" in the example script with the desired method.

Example

def ctrlInfo = ctrl?.getPageGuid()

Returns the GUID of the page that contains the control.

Snippet

def ctrl = g_rtCache.controls["<control GUID>"]
def ctrlInfo = ctrl?.myMethod()

Interface ControlInfo

Data group info

Information about the data group with the stated GUID. Replace "myMethod()" in the example script with the desired method.

Example

returns the GUID of the data group:

def dgInfo = dg?.getGuid()

Snippet

def dg = g_rtCache.dataGroups["<data group GUID>"]
def dgInfo = dg?.myMethod()

Interface DataGroupInfo

Data field info

Information about the data field with the stated GUID. Replace "myMethod()" in the example script with the desired method.

Example

Returns the GUID of the data field:

def fldInfo = fld?.getGuid()

Snippet

def fld = g_rtCache.fields["<data field GUID>"]
def fldInfo = fld?.myMethod()

Interface FieldInfo

Reference info

Returns information about the reference with the stated GUID. Replace "myMethod()" in the example script with the desired method.

Example

Returns the GUID of the reference:

def refInfo = ref?.getGuid()

Snippet

def ref = g_rtCache.references["<reference GUID>"]
def refInfo = ref?.myMethod()

Interface ReferenceInfo

Application API

JSON response (for Groovy endpoints)

The following snippet can be used in Groovy endpoints. It differs from the existing example by the absence of the json() call and especially in terms of the exception handling. The latter does not work in the Application API because it is taken over by Framework.

Snippet

// write a JSON object that is defined in Groovy
// using maps, lists, strings, numbers, ...
writeJSON("person": [
	givenName: "Donald",
	lastName: "Duck",
	age: 87,
	nephews: ["Huey", "Dewey", "Louie"]
])

Parse JSON body from request (Groovy endpoints)

The following code snippet can be used to parse JSON content that was transmitted in the body of an HTTP request.

Snippet

def json = g_json.parse(request)

Access to path variables

The following code snippet can be used to access path variables of Groovy endpoints. The values have the data type defined in the configuration of the endpoint.

"g_pathVariables" is also available in Groovy scripts of processes. However, the value can be null if the process was not triggered by a call of the Application API.

Example:

Check if path variables are present

if (g_pathVariables) {
        // do something
}

Snippet

def pathValue = g_pathVariables?.nameOfThePathVariable

Access to query variables

The following code snippet can be used to access query variables of Groovy endpoints. The values have the data type defined in the configuration of the endpoint. "g_queryParameters" is also available in Groovy scripts of processes. However, the value can be null if the process was not triggered by a call of the Application API.

Example:

Check if query variables are present

if (g_queryParameters) {
        // do something
}

Snippet

def queryValue = g_queryParameters?.nameOfTheQueryParameter

Set HTTP status code for exception

Snippet

try
{
	writeJSON("person": [
		givenName: "Donald",
		lastName: "Duck",
		age: 87,
		nephews: ["Huey", "Dewey", "Louie"]
	])

	throw new Exception("Let's test catching an exception.")
}
catch (e)
{
	g_syslog.error("Exception has been caught.", e)

	response.reset()
	response.setStatus(406)
}

Class GroovyHttpServletResponse

Set HTTP status code by exception

Snippet

import de.uplanet.net.http.HttpBadRequestException

throw new HttpBadRequestException("Set HTTP status code by exception")

writeJSON("success": true)

Class HttpErrorException

Language constants

Every text element used by default in Intrexx is defined in the global language constants. Click here for general information about this subject.

Example for accessing a global language constant:

Returns the value that the global language constant has in the default portal language. Replace "PORTAL_CONST_NAME" in the example script with the name of the desired language constant.

Example

def strValue = g_i18n.BUTTON_NEXT

Returns "Next" (label of the "Next" button, which you will find in many dialogs, in German, the default language of the sample portal).

Snippet

def strValue = g_i18n.PORTAL_CONST_NAME

Class GroovyLanguageConstants

Access global language constant in a specific language

Returns the value that the global language constant has for the specified language. Replace "PORTAL_CONST_NAME" in the example script with the name of the desired language constant.

Example

returns the value that the global language constant has in English.

def lang = g_i18n.language("en")

Snippet

def lang = g_i18n.language("language code")
def strValue = lang.PORTAL_CONST_NAME

Class GroovyLanguageConstants

Access application language constant

Returns the value that the application language constant has for the default portal language. Replace "APP_CONST_NAME" in the example script with the name of the desired language constant.

Snippet

def app = g_i18n.application("<application GUID>")
def strValue = app.APP_CONST_NAME

Class GroovyLanguageConstants

Access application language constant in a specific language

Returns the value that the application language constant has for the specified language. Replace "APP_CONST_NAME" in the example script with the name of the desired language constant. Replace the language code with the two-letter ISO code, e.g. "en" for English.

Snippet

def app = g_i18n.application("<application GUID>")
def strLang  = app.language("<language code>")
def strValue = strLang.APP_CONST_NAME

Class GroovyLanguageConstants

Imports

Intrexx AccessController

Class that can be used to check whether access requests should be allowed or denied based on the security guidelines currently in effect.

Snippet

import de.uplanet.lucy.server.security.IxAccessController

Class IxAccessController

IFilter

Snippet

import de.uplanet.util.filter.IFilter

Interface IFilter

WorkflowException

Exception handling of processes.

Snippet

import de.uplanet.lucy.server.workflow.WorkflowException

Class WorkflowException

Objects in Groovy context

PageActionHandler and PageRenderingHandler

g_appGuid

g_handlerGuid

g_page

g_action

g_appUserProfile

Save data persistently per user.

Snippet

g_appUserProfile

Class GroovyApplicationUserProfile

g_binding

Access to all bindings that are available at the time of access.

Snippet

g_binding

Class GroovyBinding

g_context

The current processing context.

Snippet

g_context

Interface IProcessingContext

g_ctx

BPEE processing context - only available in the context of a web service.

Snippet

g_ctx

g_dataCollection

The page that serves as a portlet or the DataCollection, which is then loaded.

Example 1

Access a table:

g_dataCollection.getDataRange("<GUID TABLERECORDS>").getNumberOfRecords() > 0

Example 2

Access a data record:

g_dataCollection.getValueHolder(String p_guid)

Snippet

g_dataCollection

Class GroovyDataCollection

g_dbConnections

Access available database connections.

Snippet

//System connection 
def conn = g_dbConnections.systemConnection

//External data connection
def connForeign = g_dbConnections["CONNECTION_NAME"]

Class GroovyContextConnections

g_dbQuery

Object for generating and performing database queries. Instead of "executeAndGetScalarValue", we recommend that you use the typed methods (e.g. executeAndGetScalarValueIntValue, executeAndGetScalarStringValue).

Snippet

//Build a prepared statement
def stmt = g_dbQuery.prepare(conn, "SELECT * FROM MYTABLE WHERE LID = ?")
stmt.setInt(1, iLid)
stmt.executeQuery()
stmt.close()

//Query of a single value
def iMax = g_dbQuery.executeAndGetScalarValue(conn, "SELECT MAX(LID) FROM MYTABLE", 0)

Class DbQuery

g_defaultLanguage

This string contains the language of the portal that is selected as the default language in Portal properties / Regional settings / Languages.

With println(g_defaultLanguage), for example, the corresponding language code can be written to the process log file (e.g. "de" or "en").

Example:

assert g_defaultLanguage == 'en' : 'This script requires default language en.'

Snippet

g_defaultLanguage

g_defaultLocaleId

This string contains the location-dependent format of the portal, which is selected as default in Portal properties / Regional settings / Format.

With println(g_defaultLocaleId), for example, the corresponding language code can be output in the process log file (e.g. "de" or "en").

Snippet

g_defaultLocaleId

g_dgFile

The Groovy handler can be used in Groovy workflow actions and in Groovy handlers for the Application API. It can be called via "g_dgFile".

Copying files

Examples:

g_dgFile.copy(guid: "DF GUID", id: "recordID", file: "/tmp/test.txt")
g_dgFile.copy(guid: "DF GUID", id: "recordID", files: ["/tmp/test.txt", "tmp/test1.txt"])
g_dgFile.copy(guid: "DF GUID", id: "recordID", file: [ file: "tmp/test.txt", name: "name.txt", contentType: "application/json", mode: "appendFirst"])
g_dgFile.copy(guid: "DF GUID", id: "recordID", files: [ file: "tmp/test.txt", name: "name.txt", contentType: "application/json", mode: "appendFirst"], [ file: "tmp/test1.txt", name: "name1.txt", contentType: "application/json", mode: "append"])
g_dgFile.copy(guid: "DF GUID", id: "recordID", file: "tmp/test.txt", name: "name2.txt", replaceName: "name.txt", contentType: "application/json", mode: "replace")
g_dgFile.copy(guid: "DF GUID", id: "recordID", file: "tmp/test.txt", name: "name2.txt", pos: 1, contentType: "application/json", mode: "replace")
g_dgFile.copy(guid: "DF GUID", id: "recordID", file: "tmp/test.txt", name: "name2.txt", fileId: 1, contentType: "application/json", mode: "replace")
g_dgFile.copy(guid: "DF GUID", id: "recordID", files: [[file: "tmp/test.txt", name: "name2.txt", replaceName: "name.txt", contentType: "application/json", mode: "replace"], [file: "tmp/test1.txt", name: "name3.txt", contentType: "application/json", mode: "append"], [name: "file.txt", mode: "delete"])

Parameters:

guid: Data field GUID of the file field

id: Record Id, (for composite PFs Intrexx serialization format (id= 1, lang= en) or separately for each PF)

id_%field_name%: Value for primary key field with name

replaceMode: true/false (default: false) If "true", all existing files will be replaced

triggerWorkflow: true/false (default: false) If "true", the workflow is triggered on change

file: Can be type "String", "File", "Path", "FileMap" or a FileInformation object

mode: append(default), appendFirst, replace, delete

file: The source file, type "String", "Path", "File", FileInformation (mode != delete)

For mode: append/appendFirst

name: The name of the file (must be unique, new with the API)

For mode "replace", specify either fileId, replaceName, or pos – see the following:

fileId: The file with the that id should be replaced

replaceName: The file with that name should be replaced

pos: The file at this position is to be replaced (first file has position 0)

If mode "delete", specify either fileId, name, or pos – see following:

fileId: The file with the that id should be replaced

name: The file with that name should be replaced

pos: The file at the corresponding position is to be replaced (first file is position 0)

files: Array of file, Strings (path to file), java.io.File, java.io.Path, FileInformation

Move files (like copying files)

g_dgFile.move(guid: "DF GUID", id: "recordID", file: "/tmp/test.txt", deleteAlways: true)
g_dgFile.move(guid: "DF GUID", id: "recordID", files: ["/tmp/test.txt", "tmp/test1.txt"])
g_dgFile.move(guid: "DF GUID", id: "recordID", file: "tmp/test.txt", name: "name.txt", contentType: "application/json", mode: "appendFirst")
g_dgFile.move(guid: "DF GUID", id: "recordID", files: [[file: "tmp/test.txt", name: "name.txt", contentType: "application/json", mode: "appendFirst"], [file: "tmp/test1.txt", name: "name1.txt", contentType: "application/json", mode: "append"], [ pos: 2, mode: "delete"]])
g_dgFile.move(guid: "DF GUID", id: "recordID", file: "tmp/test.txt", name: "name2.txt", replaceName: "name.txt", contentType: "application/json", mode: "replace")
g_dgFile.move(guid: "DF GUID", id: "recordID", files: [[file: "tmp/test.txt", name: "name2.txt", replaceName: "name.txt", contentType: "application/json", mode: "replace"], [file: "tmp/test2.txt", name: "name3.txt",  contentType: "application/json", mode: "append"]])

Has additional parameter "deleteAlways" (default: "false")

If deleteAlways=true, the source file will also be deleted if an error occurs while moving.

In the case of "move", FileInformation is not allowed as a source file.

Delete files

g_dgFile.delete(guid: "DF GUID", id: "recordID")
g_dgFile.delete(guid: "DF GUID", id: "recordID", fileId: 1)
g_dgFile.delete(guid: "DF GUID", id: "recordID", name: "test.txt")
g_dgFile.delete(guid: "DF GUID", id: "recordID", pos: 1)

Parameters:

guid: Data field GUID of the file field

id: Record Id, (For composite PF's Intrexx serialization format (id= 1, lang= en) or separately for each PF

id_%field_name%: Value for Primary Key field with name.

Without fileId, name or pos, all files will be deleted

fileId: Id of the file to be deleted.

name: Name of the file to be deleted

pos: Position of the file to be deleted (0 = first file)

Get files

g_dgFile.getFile(guid: "DF GUID", id: "recordID", fileId: 1) => Path
g_dgFile.getFile(guid: "DF GUID", id: "recordID", pos: 1) => Path
g_dgFile.getFile(guid: "DF GUID", id: "recordID", name: "test.txt") => Path
g_dgFile.getFileInformation(guid: "DF GUID", id: "recordID", fileName: "test.txt") => de.uplanet.lucy.server.businesslogic.util.FileInformation
g_dgFile.getFiles(guid: "DF GUID", id: "recordID", count: 3) => List<Path> (maximum number 3)
g_dgFile.getFilesInformation(guid: "DF GUID", id: "recordID", count: 3) => List<de.uplanet.lucy.server.businesslogic.util.FileDefinition>

Example for copying files with multiple PK

def sourceFile = g_dgFile.getFile(guid:"D6A9628243660FDB691B70E02CD64E860F98A82F", id_STRID: strArticleId, id_STR_LANG: g_language, pos: 0)
     if(sourceFile != null)
     {
         g_dgFile.copy(guid: "AC4DFDF9C27F23E721EAED68C276831962885FC3", id: strNewGuid, file: sourceFile, mode: "appendFirst")
     }

Remark about en.uplanet.lucy.server.businesslogic.util.FileDefinition and the methods "getFileInformation"/"getFilesInformation"

For copying, the FileInformation Object can be used as a source file parameter. This allows files to be copied from another data set.

Example:

def src = g_dgFile.getFileInformation(guid: "GUID1", id: "1", pos: 0)
g_dgFile.copy(guid: "GUID1", id: 2, file: src, mode: "appendFirst") // Copies first file of record with id 1 to first position of record with id 2.
def src = g_dgFile.getFilesInformation(guid: "GUID1", id: "1")
g_dgFile.copy(guid: "GUID1", id: 2, replaceMode: true, files: src) // Copies all files from record with id 1 and replaces the files from record with id 2.

Class GroovyDGFileHelper

g_dirWorkflow

Only available in processes- returns the directory of the current process. This directory should be read-only.

Snippet

g_dirWorkflow

Class File

g_dirWorkflowTmp

Access the process's temporary working directory on the server. The directory is available to all subsequent process elements until the process is ended.

Snippet

g_dirWorkflowTmp

Class File

g_event

Only available in processes - contains event that triggered the current workflow. Note that comparisons to the current event (see script example) must always be performed relative to the interfaces and never to the concrete classes.

Snippet

import de.uplanet.lucy.server.workflow.event.*

if (g_event instanceof IGlobalTimerWorkflowEvent)
//Insert script that responds to a timerevent here.

Interface IWorkflowEvent

g_exception

Contains the exception that was caught. This must be examined and then it must be decided whether the ErrorHandler is responsible for it. Common criteria for this are:

  • The exception was thrown by an exception of a certain type.

  • The exception was thrown by an exception of a certain type and the error message has a certain content (e.g. starts with "my-custom-prefix:").

See also readme.txt and handler_50_xxx.groovy.example in the portal directory internal/system/vm/html/errorhandler/custom.

Snippet

g_exception

Class ExceptionUtil

g_fileScript

The path of the current script as a java.io.File. This object is not available in the context of a web service.

Example

println("Executing " + g_fileScript.path)

Snippet

g_fileScript

Class File

g_guidSelf

Contains the GUID of the current process object (action, condition or event handler). This variable is only available in processes.

Snippet

g_guidSelf

g_guidWf

Contains the GUID of the current process. This variable is only available in processes.

Snippet

g_guidWf

g_i18n

Access language constants

Snippet

g_i18n

Class GroovyLanguageConstants

g_json

The g_json object implements a few simple use cases related to JSON:

  • Parsing JSON text

  • Serializing objects as JSON text

  • Generating JSON objects

  • Sending GET requests and parsing the response as JSON

Example of JSON parsing

def strJson = '''{"person": {
	"givenName": "Donald",
	"lastName": "Duck",
	"age": 87,
	"nephews": ["Huey", "Dewey", "Louie"]
}}'''

def parsed = g_json.parse(strJson)

println(parsed.person.lastName)
println(parsed.person.givenName)

Snippet

g_json

Class GroovyJSON

g_language

This string contains the language of the current user, which is set in his account in the user management under "Organization".

With println(g_language) e.g. the corresponding language code can be written to the process log file (e.g. "de" or "en").

Snippet

g_language

g_localeId

This string contains the format of the current user, which is set in his account in the user management under "Organization".

With println(g_localeId) e.g. the corresponding language code can be written to the process log file (e.g. "de" or "en").

Snippet

g_localeId

g_log

Writes the entry in the log file that belongs to the processing context of the script.

Snippet

g_log.info("Process finished without errors.")
g_log.error("An error has occurred.")

Logging

g_om

Object for accessing the user management.

g_om

g_om Details

Details

Intrexx provides a wide range of extended options for process-controlled user management. With access objects and methods, new users, among other things, can be created and managed in Groovy actions. The globally available, pre-initialized object "g_om" serves as an entry point for the portal organizational structure in processes. With this object, principle use cases such as searching for a user or generating a new password can be implemented. These methods can be used as "normal" method calls. All available methods can be found in our JavaDocs:

Class GroovyOrgBuilder

Class GroovyOrgStructureWrapper

Examples

//Change password of the passed user
g_om.changePassword(g_session.user, "SECRET")
//Generate and send a new password to the passed user
g_om.generateAndSendPassword(g_session.user)
//Search a user by means of a GUID
def user = g_om.getUser("C10579449052F85D9C3FF3C2824348FCE020A22E")
//Classify a list of GUIDs
//A list of GUIDs or a text can be passed, e.g. the content of a data field of a multiple selection element
def guids = ["AE39A904172F5867DA23DE289D1D6B7967420DC0", "6AA80844C3C99EF93BF4536EB18605BF86FDD3C5", g_session.user.guid]
			 
def classified = g_om.classifyGuids(guids) //guids = Collection or String

//Results in a map with categorized GUIDs, e.g. {containers=[], users=[7312F993D0DA4CECCA9AE5A9D865BE142DE413EA], 
//      unclassified=[AE39A904172F5867DA23DE289D1D6B7967420DC0], 
//      sets=[6AA80844C3C99EF93BF4536EB18605BF86FDD3C5]}
println(classified)

//filter on object types
println(classified.users)
println(classified.containers)
println(classified.sets)
println(classified.unclassified)

//number of non anonymous sessions
g_om.getNonAnonymousActiveSessionCount()

In addition, the object "g_om" has access to more methods that can be called in conjunction with a closure to implement subsequent actions. These methods can be recognized by the groovy.lang.Closure parameter specified in the JavaDocs, e.g. GroovyOrgBuilder.createUser(groovy.lang.Closure p_closure). Within such a closure, methods of any class can be called that are documented in each of the defined links. The following methods can be called with a closure:

g_om.createUser(groovy.lang.Closure p_closure)

A new Intrexx user can be created with this. The following properties can be set within the closure, where the properties name and loginName are required, the others are optional.

Property

Data type

birthday

Date

city

String

container

Object

country

String

defaultLanguage

String

defaultLayout

String

deletable

Boolean

deleted

Boolean

description

String

disabled

Boolean

dn

String

emailBiz

String

emailHome

String

employeeNo

String

enterDate

Date

externalLogin1

String

externalLogin2

String

externalLogin3

String

externalPassword1

String

externalPassword2

String

externalPassword3

String

externalPrimaryGroupId

Integer

female

Boolean

firstName

String

fullName

String

gender

Integer

guid

String

id

Integer

internalUsn

Integer

lastName

String

loginDomain

String

loginDomainLwr

String

loginName

String

loginNameLwr

String

male

Boolean

memberOf

Collection<?>

middleName

String

name

String

password

String

passwordChangedDate

Date

passwordExpires

Boolean

passwordHash

String

phoneBiz

String

phoneFax

String

phoneHome

String

phoneMobileBiz

String

phoneMobileHome

String

phonePager

String

poBox

String

postalCode

String

priority

Integer

rplGuid

String

salt

String

showUser

Boolean

state

String

street

String

timeZone

TimeZone

title

String

userImageContentType

String

userImageFile

File

userImageMetaInfo

String

For the "container" and "memberOf" properties, you can optionally specify the GUIDs, the unique names of the containers, roles, sets or groups and paths in the organizational structure.

Example

g_om.createUser 
{
    name      	= "g_om"
    loginName 	= "g_om"
    birthday  	= now()
    container 	= "0F8233A39555B28F6B32CFFE666A5151E1F41AD3"
    memberOf 	= ["8FBF199EE826D16742F0F131E0AB4CF0E6BA6CA3", "Benutzer"]
    emailBiz  	= "g_om@example.org"
    guid      	= newGuid()
    male      	= true
}
g_om.getLoggedOnUsers(boolean p_bIncludeAnonymous, groovy.lang.Closure p_closure)

Returns all currently logged-in users. "p_bIncludeAnonymous" allows you to define whether anonymous sessions should be included in the result. Additional filters can be applied via the Groovy closure.

Example

def userOnline = g_om.getLoggedOnUsers(false) {
    it.containerGuid == "9DABA9EE4F9F6F771704F75C79A1C3A124FF399C"
}
g_om.getLoggedOnUsersDistinct(groovy.lang.Closure p_closure)

Returns all currently logged-in, non-anonymous users without double entries. Additional filters can be applied via the Groovy closure in the same way as "g_om.getLoggedOnUsers(boolean p_bIncludeAnonymous, groovy.lang.Closure p_closure)”.

g_om.withOrgStructure(groovy.lang.Closure p_closure)

Allows you to work in the portal organizational structure.

Example

g_om.withOrgStructure {
    println("9DABA9EE4F9F6F771704F75C79A1C3A124FF399C".isUser())
}

The following methods can be called within the OrgStructure closure:

  • isUser()

  • isSet()

  • isGroup()

  • isDistList()

  • isContainer()

  • isOrganization()

  • isOrgUnit()

g_om.getMembers(java.lang.Object,boolean)

Generates a list of the GUIDs of all users that belong to a specific or multiple groups.

Example

def userGuids = g_om.getMembers(["00A303288634E154D755732E478F2BE0D9AD36F7"], false)*.guid

"00A303288634E154D755732E478F2BE0D9AD36F7" is the GUID of the group copied from the "User" module. Multiple group GUIDs or set GUIDs can be entered. More information about this is available here:

https://docs.intrexx.com/intrexx/version/10000/api/groovy/jdk/de/uplanet/lucy/server/usermanager/groovy/GroovyOrgBuilder.html#getMembers(java.util.Collection,boolean)

Class GroovyOrgBuilder

g_parameter

Object for accessing parameters.

Example

def customerid = g_parameter.get("customerid")

Snippet

g_parameter

Class GroovyParameter

Page properties - Parameter tab

g_permissions

This class is intended to check and query permissions. The usage is shown in the "JSON response" template for the use case there. Check checkPermission(Permission) and check(Closure) as to whether the desired permissions are granted. Otherwise, a java.security.AccessControlException is thrown. hasPermission(Permission) and has(Closure) work analogously, but return a boolean value that indicates whether or not the requested permissions have been granted. The closure methods delegate to the above-mentioned GroovyIxAccessControllerDelegate object and require a map that assigns actions to the object names. Example: Check access permissions to the application <application GUID>, read permissions to the data group <data group GUID> and write permissions to the data group <another data group GUID>.

Example

g_permissions.check {
    application("<application GUID>": "access")
    dataGroup("<data group GUID>": "read", "<another data group GUID>": "write,create")
}

Snippet

g_permissions

Class GroovyIxAccessController

Class GroovyIxAccessController.GroovyIxAccessControllerDelegate

Classes from de.uplanet.lucy.security.permission

g_portal

Object for accessing portal properties such as name or base URL.

Example

def strUrl = g_portal.baseUrl

Snippet

g_portal

Class GroovyPortalInfo

g_portlet

Access the respective portlet that should be filtered (in the portlet pool or when rendering the portlet).

Snippet

g_portlet

Class GroovyPortlet

g_portletPool

Access the portlet pool that should be filtered (collection of portlets), firstly in the portlet pool itself and secondly when rendering the portlet.

Snippet

g_portletPool

Class GroovyPortlet

g_record

Access the current data record.

Example

def iLid = g_record["0D8F13B2B43B128DB23C0C1CC8C5DC1143C9D826"].value // datafield (PK) (S) ID

Snippet

g_record

Class ReadOnlyGroovyRecord

g_rwRecord

Read and write access to the current data record. Can only be used within Groovy PageActionHandlers.

Example

def iLid = g_rwRecord["0D8F13B2B43B128DB23C0C1CC8C5DC1143C9D826"].value // datafield (PK) (S) ID

Snippet

g_rwRecord

Class ReadWriteGroovyRecord

g_request

Access the current request, e.g. to read request variables in the process. This variable is only defined if the script was called through a web request.

Snippet

g_request

Class GroovyServerBridgeRequest

g_rtCache

RtCache - Access to data groups, applications, fields etc.

Example

//Find all data groups of the application with the GUID 68C97BF4D89E8466BDE08AF03A4EF95F5B23AF72
def datagroups = g_rtCache.dataGroups.findAll {it.appGuid == "68C97BF4D89E8466BDE08AF03A4EF95F5B23AF72"}
		

Snippet

g_rtCache

Class GroovyRtCache

g_session

The current session.

Example

//Name of the currently logged-in user
def strUserName = g_session?.user?.name

Snippet

g_session

Class GroovySession

sharedState

sharedState where variables and values can be written and read later.

Example

//write variable to shared state
g_sharedState.meineVariable = "my value"
//read variable from shared state
def strValue = g_sharedState.myVariable

Snippet

g_sharedState

Class SharedState

g_sourcePage

Returns, for example, the GUID, application GUID or RecID of the page that sends parameters.

Example

def strMyPage = g_sourcePage.getPageGuid()
g_log.info(strMyPage)

Snippet

g_sourcePage

Class GroovySourcePage

g_springApplicationContext

Spring application context.

Snippet

g_springApplicationContext

Interface ApplicationContext

g_store

The following script shows how to use g_store.ephemeral to set a system-wide retrievable ephemeral name-value pair and consume it elsewhere.

Snippet

//------------------------------ supplier side ------------------------------
// initially no value exists for myUniqueKey
assert g_store.ephemeral.contains('myUniqueKey') == false

// insert an ephemeral value (does not survive portal service restart)
g_store.ephemeral.put('myUniqueKey', 'foo')

// now the value exists
assert g_store.ephemeral.contains('myUniqueKey') == true


//------------------------------ consumer side side ------------------------------
assert g_store.ephemeral.contains('myUniqueKey') == true

// get the ephemeral value
def val = g_store.ephemeral.remove('myUniqueKey')
assert val == 'foo'

// no the value does not exist anymore
assert g_store.ephemeral.contains('myUniqueKey') == false

Class GroovyInternalStore

g_sysDg

With this object, values can be read from a system data group.

Example

//Specify the Guid of the system data field as GUID
def strValue            = g_sysDg['C1BFDD165EBFD0713D306D3E2B124E80021E613F']
def strValueByFieldGuid = g_sysDg.getValueByFieldGuid('C1BFDD165EBFD0713D306D3E2B124E80021E613F')
def vhByFieldGuid       = g_sysDg.getValueHolderByFieldGuid('C1BFDD165EBFD0713D306D3E2B124E80021E613F')

Snippet

g_sysDg

Class GroovySystemDataGroup

g_syslog

Logging object for writing to the portal log file (portal.log).

Snippet

g_syslog.info("my message in portal.log.")

g_ws

Object for explicitly calling a web service. Only available in scripts that are defined in a web service.

Snippet

g_ws.invoke()

Closures

The predefined closures can be called in the same way as functions.

checkInterrupted()

Checks whether either

  • the thread that performs the process has received an interrupt request from another thread or

  • the timeout defined for the process has been exceeded.

Use this call in scripts that should behave cooperatively in such cases.

Snippet

checkInterrupted()

Class CheckInterruptedClosure

createTemporaryDirectory()

Generates a temporary working directory that is available until the process has ended.

Snippet

createTemporaryDirectory()

Class CreateTemporaryDirectoryClosure

currentTimestamp()

This closure returns the timestamp of the current transaction. This value is not changed until the transaction has finished being processed.

Example

def dtNow = currentTimestamp()

Snippet

currentTimestamp()

Class CurrentTimestampClosure

getStackTraceString()

Returns the entire StackTrace of an occurred error as a string. The closure "getStackTraceString()" requires a parameter with the type java.lang.Throwable, i.e. an exception.

Snippet

try
{
    trySomething()

}
catch (e)
{
    def strStackTrace = getStackTraceString(e)

    doSomethingWithStackTrace(strStackTrace)
}

Class CreateStackTraceStringClosure

newGuid()

Generates a new GUID.

Snippet

newGuid()

Class NewGuidClosure

now()

Generates a new date (now) as a timestamp or ValueHolder.

Snippet

now()

Class NowClosure

parseGuids(strText)

Parses GUIDs from the transferred string (e.g. as a pipe-separated list) and returns a TreeSet with the found GUIDs.

Snippet

def strText = "18CC231E0A71F6F27091855C4C0FD0D6F2F26038||D0CACC8058DC36A9A499AB2DD3B993F427AB9200"
def guids   = parseGuids(strText)
guids.each {println it}

Class ParseGuidsClosure

vh()

Generates a new ValueHolder from the transferred object.

Snippet

def vhTest = vh("Hello world!")
def vhInt  = vh(1000)

Class CreateValueHolderClosure

Databases

Data groups

Find data group via GUID

How to identify the name of a data group:
def strName = g_rtCache.dataGroups["C399FB1F398D76E91BC7DC679E1E4DDB9F5CEB9C"].name

Snippet

def strName = g_rtCache.dataGroups["<data group GUID"].name

Interface DataGroupInfo

Reference data group in SQL via GUID

So that you don't have to use a static data group name in SQL statements, thus avoiding problems when importing or making changes to the data group, a data group can be referenced using its GUID instead of its name with the aid of this client function. This is only available via the Intrexx database API.

Example

g_dbQuery.executeAndGetScalarValue(conn, "SELECT COUNT(LID) FROM DATAGROUP('DAF7CECF66481FCABE50E529828116EAFE906962')")

Instead of "executeAndGetScalarValue", we recommend that you use the typed methods (e.g. executeAndGetScalarValueIntValue, executeAndGetScalarStringValue).

Snippet

def strName = g_rtCache.dataGroups["<data group GUID>"].name

Interface DataGroupInfo

Get all column names of a data group

Returns a list of column names from the data group with the stated GUID.

Snippet

def fieldNames = g_rtCache.fields.findAll{it.dataGroupGuid == "DG-GUID"}*.columnName

Interface FieldInfo

Intrexx database API

Prepared statement with SELECT

Executes a SELECT statement as a prepared query. Afterwards it is iterated over the results in the result set.

Example

stmt = g_dbQuery.prepare(conn, "SELECT * FROM DATAGROUP('7AFAF7CB5DE281D35F05D96FCD96CE27692C110F') WHERE ID = ?")
stmt.setInt(1, 1)
stmt.executeQuery()
stmt = Safely.close(stmt)

Snippet

import de.uplanet.scripting.groovy.util.Safely

def conn = g_dbConnections.systemConnection
def stmt = null
def rs   = null

try
{
        stmt = g_dbQuery.prepare(conn, "SELECT <COLUMNS> FROM DATAGROUP('<DATAGROUP_GUID>') WHERE <CONDITION>")
	
        //stmt.setInt(1, 1)
	
        rs = stmt.executeQuery()
	
        while (rs.next())
        {
            // do something
            // rs.getIntValue(1)
            // rs.getStringValue(2)
            // rs.getBooleanValue(3)
            // rs.getTimestampValue(4)
        }
	
        rs   = Safely.close(rs)
        stmt = Safely.close(stmt)
}
finally
{
        rs   = Safely.close(rs)
        stmt = Safely.close(stmt)
}

Class DbPreparedStatement

Prepared statement with INSERT

Executes an INSERT statement as a prepared query.

Example

stmt = g_dbQuery.prepare(conn, "INSERT INTO DATAGROUP('7AFAF7CB5DE281D35F05D96FCD96CE27692C110F') (ID, STRTEXT, DTDATE, BBOOLEAN) VALUES (?,?,?,?)")
stmt.setInt(1, 1)
stmt.setString(2, "Example text")
stmt.setTimestamp(3, now().withoutFractionalSeconds)
stmt.setBoolean(4, true)

Snippet

import de.uplanet.scripting.groovy.util.Safely

def conn = g_dbConnections.systemConnection
def stmt = null

try
{
	stmt = g_dbQuery.prepare(conn, "INSERT INTO DATAGROUP('<DATAGROUP_GUID>') (<COLUMNS>) VALUES ()")
	
	//stmt.setInt(1, 1)
	//stmt.setString(2, "Example text")
	//stmt.setTimestamp(3, now().withoutFractionalSeconds)
	//stmt.setBoolean(4, true)
	
	stmt.executeUpdate()

	stmt = Safely.close(stmt)
}
finally
{
	stmt = Safely.close(stmt)
}

Class DbPreparedStatement

Prepared statement with INSERT (with closure)

Executes an INSERT statement with a closure as a prepared query.

Example

def conn = g_dbConnections.systemConnection

g_dbQuery.executeUpdate(conn, "INSERT INTO DATAGROUP('7AFAF7CB5DE281D35F05D96FCD96CE27692C110F') (LID, STRTEXT, DATE) VALUES (?,?,?)") {
	setInt(1, 1)
	setString(2, "Example text")
	setTimestamp(3, now().withoutFractionalSeconds)
}

Please note: If the statement is to be reused, e.g. within a loop, the prepared statement version without a closure is more efficient.

Snippet

def conn = g_dbConnections.systemConnection

g_dbQuery.executeUpdate(conn, "INSERT INTO DATAGROUP('<DATAGROUP_GUID>') (<COLUMNS>) VALUES ()") {
	//setString(1, "Example text")
	//setTimestamp(2, now().withoutFractionalSeconds)
	//setBoolean(3, true)
}

Class DbQuery

Prepared statement with UPDATE

Executes an UPDATE statement as a prepared query.

Example

try
{				
	stmt = g_dbQuery.prepare(conn, "UPDATE DATAGROUP('7AFAF7CB5DE281D35F05D96FCD96CE27692C110F') SET STRTEXT = ?, DTDATE = ?, BBOOLEAN = ? WHERE ID = ?")
	
	stmt.setString(1, "Example text")
	stmt.setTimestamp(2, now().withoutFractionalSeconds)
	stmt.setBoolean(3, true)
	stmt.setInt(4, 1)
	
	stmt.executeUpdate()
	stmt = Safely.close(stmt)
}
finally
{
	stmt = Safely.close(stmt)
}			

Snippet

import de.uplanet.scripting.groovy.util.Safely

def conn = g_dbConnections.systemConnection
def stmt = null

try
{
	stmt = g_dbQuery.prepare(conn, "UPDATE DATAGROUP('<DATAGROUP_GUID>') SET <COLUMNS> = ? WHERE <CONDITION>")
	
	//stmt.setInt(1, 1)
	//stmt.setString(2, "Example text")
	//stmt.setTimestamp(3, now().withoutFractionalSeconds)
	//stmt.setBoolean(4, true)
	
	stmt.executeUpdate()

	stmt = Safely.close(stmt)
}
finally
{
	stmt = Safely.close(stmt)
}

Class DbPreparedStatement

Prepared statement with UPDATE (with closure)

Executes an UPDATE statement with a closure as a prepared query.

Example

def conn = g_dbConnections.systemConnection

g_dbQuery.executeUpdate(conn, "UPDATE DATAGROUP('7AFAF7CB5DE281D35F05D96FCD96CE27692C110F') SET STRTEXT = ? WHERE DATE < ?") {
	setString(1, "Example text")
	setTimestamp(2, now().withoutFractionalSeconds)
}

Please note: If the statement is to be reused, e.g. within a loop, the prepared statement version without a closure is more efficient.

Snippet

def conn = g_dbConnections.systemConnection

g_dbQuery.executeUpdate(conn, "UPDATE DATAGROUP('<DATAGROUP_GUID>') SET <COLUMNS> = ? WHERE <CONDITION>") {
	//setString(1, "Example text")
	//setTimestamp(2, now().withoutFractionalSeconds)
	//setBoolean(3, true)
}

Class DbQuery

Prepared statement with DELETE

Executes a DELETE statement as a prepared query.

Example

def conn = g_dbConnections.systemConnection
def stmt = null

try
{
	stmt = g_dbQuery.prepare(conn, "DELETE FROM DATAGROUP('7AFAF7CB5DE281D35F05D96FCD96CE27692C110F') WHERE ID > ?")

	stmt.setInt(1, 5)
	stmt.executeUpdate()
	stmt = Safely.close(stmt)
}
finally
{
	stmt = Safely.close(stmt)
}

Snippet

import de.uplanet.scripting.groovy.util.Safely

def conn = g_dbConnections.systemConnection
def stmt = null

try
{
	stmt = g_dbQuery.prepare(conn, "DELETE FROM DATAGROUP('<DATAGROUP_GUID>') WHERE <CONDITION>")
	
	//stmt.setInt(1, 1)
	//stmt.setString(2, "Example text")
	//stmt.setTimestamp(3, now().withoutFractionalSeconds)
	//stmt.setBoolean(4, true)
	
	stmt.executeUpdate()
	
	stmt = Safely.close(stmt)
}
finally
{
	stmt = Safely.close(stmt)
}

Class DbPreparedStatement

Prepared statement with DELETE (with closure)

Executes an DELETE statement with a closure as a prepared query.

Example

def conn = g_dbConnections.systemConnection

g_dbQuery.executeUpdate(conn, "DELETE FROM DATAGROUP('7AFAF7CB5DE281D35F05D96FCD96CE27692C110F') WHERE ID > ?"){

	setInt(1, 5)
}

Please note: If the statement is to be reused, e.g. within a loop, the prepared statement version without a closure is more efficient.

Snippet

def conn = g_dbConnections.systemConnection

g_dbQuery.executeUpdate(conn, "DELETE FROM DATAGROUP('<DATAGROUP_GUID>') WHERE <CONDITION>"){

	//setInt(1, 1)
	//setString(2, "Example text")
	//setTimestamp(3, now().withoutFractionalSeconds)
	//setBoolean(4, true)

Class DbPreparedStatement

Read a single value from a database query

Reads a single value from a database query. If the result set is empty, or the value is null, the fallbackValue is returned. If the return data type should be defined more precisely, typed method calls such as executeAndGetScalarBooleanValue(...) can be used.

Example

def value = g_dbQuery.executeAndGetScalarValue(conn, "SELECT MAX(ID) FROM DATAGROUP('7AFAF7CB5DE281D35F05D96FCD96CE27692C110F')", 0)

or with a prepared statement

def value = g_dbQuery.executeAndGetScalarValue(conn, "SELECT MAX(ID) FROM DATAGROUP('7AFAF7CB5DE281D35F05D96FCD96CE27692C110F') WHERE DTEDIT < ?", 0) {
setTimestamp(1, now().withoutFractionalSeconds)

Instead of "executeAndGetScalarValue", we recommend that you use the typed methods (e.g. executeAndGetScalarValueIntValue, executeAndGetScalarStringValue).

Snippet

def conn = g_dbConnections.systemConnection

def value = g_dbQuery.executeAndGetScalarValue(conn, "SELECT <COLUMNS> FROM DATAGROUP('<DATAGROUP_GUID>') WHERE <CONDITION>", <FALLBACK VALUE>) {
	//setString(1, "Example text.")
}

Class DbQuery

Read a single value using a prepared database query

Reads a single value from a database query. If the result set is empty, or the value is null, the fallbackValue is returned. If the return data type should be defined more precisely, typed method calls such as executeAndGetScalarBooleanValue(...) can be used.

Example

def stmt = g_dbQuery.prepare(conn, "SELECT MAX(LID) FROM DATAGROUP('7AFAF7CB5DE281D35F05D96FCD96CE27692C110F')")

def value = stmt.executeAndGetScalarValue(0)

stmt = Safely.close(stmt)

Instead of "executeAndGetScalarValue", we recommend that you use the typed methods (e.g. executeAndGetScalarValueIntValue, executeAndGetScalarStringValue).

Snippet

import de.uplanet.scripting.groovy.util.Safely

def conn  = g_dbConnections.systemConnection
def stmt  = null
def value

try
{
	stmt = g_dbQuery.prepare(conn, "SELECT <COLUMN> FROM DATAGROUP('<DATAGROUP_GUID>') WHERE <CONDITION>")

	//stmt.setInt(1, 1)
	//stmt.setString(2 , "Example text")
	//stmt.setTimestamp(3, now().withoutFractionalSeconds)
	//stmt.setBoolean(4, false)

	value = stmt.executeAndGetScalarValue(<FALLBACK_VALUE>)

	stmt = Safely.close(stmt)
}
finally
{
	stmt = Safely.close(stmt)
}

Class DbPreparedStatement

JDBC

Prepared statement with SELECT

Executes a SELECT statement as a prepared query. Afterwards it is iterated over the results in the result set.

Snippet

import de.uplanet.scripting.groovy.util.Safely

def conn = g_dbConnections.systemConnection
def stmt = null
def rs   = null

try
{
	stmt = conn.prepareStatement("SELECT <COLUMNS> FROM <DATAGROUP_NAME> WHERE <CONDITION>")

	//stmt.setInt(1, 42)
	//stmt.setString(2, "Example text")
	//stmt.setTimestamp(3, now().withoutFractionalSeconds)
	//stmt.setBoolean(4, false)

	rs = stmt.executeQuery()

	while (rs.next())
	{
		// do something
		// rs.getInt(1)
		// rs.getString(2)
		// rs.getTimestamp(3)
	}
}
finally
{
	rs   = Safely.close(rs)
	stmt = Safely.close(stmt)
}

Interface PreparedStatement

Prepared statement with INSERT

Executes an INSERT statement as a prepared query.

Snippet

import de.uplanet.scripting.groovy.util.Safely

def conn = g_dbConnections.systemConnection
def stmt = null

try
{
	stmt = conn.prepareStatement("INSERT INTO <DATAGROUP_NAME> (<COLUMNS>) VALUES ()")

	// stmt.setInt(1, 1234)
	// stmt.setString(2, "Example text")
	// stmt.setBoolean(3, true)
	// stmt.setTimestamp(4, now().withoutFractionalSeconds)

	stmt.executeUpdate()
}
finally
{
	stmt = Safely.close(stmt)
}

Interface PreparedStatement

Prepared statement with UPDATE

Executes an UPDATE statement as a prepared query.

Snippet

import de.uplanet.scripting.groovy.util.Safely

def conn = g_dbConnections.systemConnection
def stmt = null

try
{
stmt = conn.prepareStatement("UPDATE <DATAGROUP_NAME> SET <COLUMNS> = ? WHERE <CONDITION>")

			// stmt.setInt(1, 1234)
			// stmt.setString(2, "Example text")
			// stmt.setBoolean(3, true)
			// stmt.setTimestamp(4, now().withoutFractionalSeconds)

			stmt.executeUpdate()
			}
			finally
			{
			stmt = Safely.close(stmt)
			}

Interface PreparedStatement

Prepared statement with DELETE

Executes a DELETE statement as a prepared query.

Snippet

import de.uplanet.scripting.groovy.util.Safely

def conn = g_dbConnections.systemConnection
def stmt = null

try
{
	stmt = conn.prepareStatement("DELETE FROM <DATAGROUP_NAME> WHERE <CONDITION>")

	// stmt.setInt(1, 1234)
	// stmt.setString(2, "Example text")
	// stmt.setBoolean(3, true)
	// stmt.setTimestamp(4, now().withoutFractionalSeconds)

	stmt.executeUpdate()
}
finally
{
	stmt = Safely.close(stmt)
}

Interface PreparedStatement

System data source

System database connection.

Example

def conn = g_dbConnections.systemConnection

Snippet

g_dbConnections.systemConnection

Class GroovyContextConnections

External data source

Connection to an external data source. The name to use is the given name of the external connection defined in the Integration module.

Example

def conn = g_dbConnections["ForeignData"]

Snippet

g_dbConnections["<CONNECTION_NAME>"]

Class GroovyContextConnections

Determine the database type

Identifies the type of database.

Snippet

def conn = g_dbConnections.systemConnection

switch (conn.descriptor.databaseType)
{
	case "Db2":
		// DB2
		break

	case "Derby":
		// Derby/Java DB
		break

	case "Firebird":
		// Firebird
		break

	case "HSQLDB":
		// HSQLDB
		break

	case "Ingres":
		// Ingres
		break

	case "Oracle8":
		// Oracle 8
		break

	case "Oracle9":
		// Oracle 9
		break

	case "Oracle10":
		// Oracle 10
		break

	case "PostgreSQL":
		// PostgreSQL
		break

	case "MaxDB":
		// MaxDB
		break

	case "MsSqlServer":
		// Microsoft SQL Server
		break

	case "Standard":
		// unspecified
		break

	default:
		assert false : "Unexpected database type."
		break
}

Class GroovyContextConnections

Web services

Execute web service call

Calls the underlying web service. Only valid for scripts defined within a web service.

Snippet

g_ws.invoke()

Read web service input values

Read values defined as input parameters for a web service. Use the name of the control, which contains the value, as the variable name.

Example

g_ctx.requestVars.textcontrolD72A9620

Snippet

g_ctx.requestVars.

Read web service response values

Read values defined as response parameters from a web service. Use the name of the control, where the response value will be written, as the variable name.

Example

g_ctx.bpeeVars.textvcontrol72EF4A0B.value

Snippet

g_ctx.bpeeVars..value

Case differentiation

switch statement for Groovy condition

Usable in processes. The returned values correspond to the outgoing connections (connection ID) of the Groovy condition.

Snippet

switch (g_record[""].value)
{
	case "expected value 1":
		return connectionId1
	case "expected value 2":
		return connectionId2
	default:
		return connectionId3
}

switch / case

switch statement for data group events

Usable in processes.

Snippet

import de.uplanet.lucy.server.workflow.event.IAfterCreateDataGroupWorkflowEvent
import de.uplanet.lucy.server.workflow.event.IAfterUpdateDataGroupWorkflowEvent
import de.uplanet.lucy.server.workflow.event.IBeforeDeleteDataGroupWorkflowEvent
import de.uplanet.lucy.server.workflow.event.INotifyDataGroupWorkflowEvent

switch (g_event)
{
	case IAfterCreateDataGroupWorkflowEvent:
		g_log.info("A new record was inserted.")
		break

	case IAfterUpdateDataGroupWorkflowEvent:
		g_log.info("A record was updated.")
		break

	case IBeforeDeleteDataGroupWorkflowEvent:
		g_log.info("A record will be deleted.")
		break

	case INotifyDataGroupWorkflowEvent:
		g_log.info("A timer resubmitted a record.")
		break

	default:
		g_log.warn("Unhandled event ${g_event}.")
		break
}

Interface IWorkflowEvent

Records from global data group timers

Distinguish the first record from the subsequent records that are delivered by a global data group timer.

Snippet

if (g_sharedState["wasHere${g_guidSelf}"])
{
	// we were here before
}
else
{
	// we are here for the first time
	g_sharedState["wasHere${g_guidSelf}"] = true
}

Mathematical calculations

Business rounding

Round half away from zero with the option of defining the number of decimal places.

Example

 13,3749 ->  13,37
-13,3749 -> -13,37
 13,3750 ->  13,38
-13,3750 -> -13,38

Snippet

import de.uplanet.util.math.RoundingUtil
RoundingUtil.roundHalfAwayFromZero(, 2)

Class Math

Mathematical rounding

Round to even with the option of defining the number of decimal places.

Example

2.2499 -> 2.2
2.2501 -> 2.3
2.2500 -> 2.2
2.3500 -> 2.4

Snippet

import de.uplanet.util.math.RoundingUtil
RoundingUtil.roundHalfEven(, 2)

Class Math

Date / Time

Formatting date values

Here you can find script for formatting date values.

Snippet

import java.text.SimpleDateFormat

// specify the time zone
def tz = g_session.user.timeZone
//def tz = de.uplanet.lucy.server.DefaultTimeZone.get()
//def tz = TimeZone.getTimeZone("Europe/Berlin")

assert tz != null

// the date/time to be formatted
def dt = new Date()

// the date format
// https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/text/SimpleDateFormat.html
def fmt = new SimpleDateFormat("yyyy-MM-dd")
fmt.setTimeZone(tz)

println(fmt.format(dt))

SimpleDateFormat

Duration in days

A data record contains data for a start and an end date. The duration between these two date values is calculated. Please note that time zones are not considered.

Snippet

def conn    = g_dbConnections.systemConnection
def dtStart = g_record["GUID"].value // datafield startDate
def dtEnd   = g_record["GUID"].value // datafield endDate
def iID     = g_record["GUID"].value // datafield (PK) (S) ID

use (groovy.time.TimeCategory)
{
	def duration = dtEnd - dtStart

	def stmt = g_dbQuery.prepare(conn, "UPDATE DATAGROUP('<DATAGROUP_GUID>') SET <COLUMN_DURATION> = ? WHERE LID = ?")

	stmt.setInt(1, duration.days)
	stmt.setInt(2, iID)
	stmt.executeUpdate()
	stmt.close()
}

Parse ISO date string

Parses an ISO formatted string into an "java.util.Date" object.

Example

def strDate        = "2013-01-01T12:00:01Z"
def strDateMillis = "2013-01-01T15:00:01.000Z"

def dtDate1 = ISODateTimeUtil.parseISODateTime(strDate)
def dtDate2 = ISODateTimeUtil.parseISODateTimeMillis(strDateMillis)
def dtDate3 = ISODateTimeUtil.parseISODateTimeOptionalMillis(strDate)
def dtDate4 = ISODateTimeUtil.parseISODateTimeOptionalMillis(strDateMillis)

Snippet

import de.uplanet.util.ISODateTimeUtil

def dtDate  = ISODateTimeUtil.parseISODateTimeOptionalMillis("<DATE_ISO_STRING>")

Class ISODateTimeUtil

Parse date to ISO string

Formats a date object as an ISO string.

Example

println ISODateTimeUtil.formatISODateTime(currentTimestamp())
println ISODateTimeUtil.formatISODateTimeMillis(currentTimestamp())

Snippet

import de.uplanet.util.ISODateTimeUtil

ISODateTimeUtil.formatISODateTime(currentTimestamp())

Class ISODateTimeUtil

Now as timestamp

Snippet

now().withoutFractionalSeconds

Class ChimeraDate

Timestamp for system values

This closure returns the timestamp of the current transaction. This value is not changed until the transaction has finished being processed.

Snippet

currentTimestamp()

Class CurrentTimestampClosure

Email

Groovy email (simple)

Create a simple text email.

Snippet

import de.uplanet.lucy.server.mail.GroovyMailBuilder
	def mail = new GroovyMailBuilder().composeMail {
	from    = "sender@example.org"
	to      = "recipient@example.org"
	subject = "Insert the subject here"

	body << "Hello world"
}

mail.drop()

Class GroovyMailBuilder

Groovy email

Create an HTML email with inline images and attachment.

Snippet

import de.uplanet.lucy.server.mail.GroovyMailBuilder

def fileImg        = new File(g_dirWorkflow, "theImage.png")
def fileAttachment = new File(g_dirWorkflow, "document.pdf")

def mail = new GroovyMailBuilder().composeMail {
	headers = [
		"Importance": "High",
		"X-Priority": "1"
		]

	from        = "sender@example.org"
	to          = ["recipient-1@example.org", "recipient-2@example.org"]
	subject     = "Insert the subject here"
	contentType = "text/html; charset=UTF-8"

	body << """<html>
	<body>
		<h1>Hello World</h1>
		<p>
			Look at this image
			<br>
			<img src="${srcInlineImage(fileImg)}">
			<br>
			Nice.
		</p>
	</body>
	</html>"""

	// note: name is an optional parameter
	attachFile(file: fileAttachment, name: "nameOfTheAttachment.pdf", contentType: "application/pdf")
}

mail.drop()

Class GroovyMailBuilder

Send email via Ant

Please note: Sending the email is not part of the transaction, but is executed immediately and regardless of the success of the transaction.

Snippet

def strFromAddr = g_session?.user?.emailBiz
def strFromName = g_session?.user?.name
def strToAddr   = "" // insert the recipient here

new AntBuilder().mail(mailhost:"localhost", messagemimetype:"text/plain", subject:"Hello World") {
	from(address:"${strFromName} <${strFromAddr}>")
	to(address:addrTo)
	message("""Here goes the message text.

With kind regards
${strFromName}
""")
}

Files and directories

Identify disk space

Identifies the free and total disk space.

Snippet

// the partition where the Intrexx portal resides
File partition = new File(".")

long totalSpace = partition.totalSpace
long freeSpace = partition.freeSpace

Class File

The directory of the current workflow

Returns the directory of the current process. This directory should be read-only.

Snippet

g_dirWorkflow

Class File

Temporary workflow directory

Access a temporary workflow directory. The directory is also available to subsequent workflow objects. It is deleted as soon as the workflow has been fully executed.

Snippet

g_dirWorkflowTmp

Class File

Work in a temporary directory

Uses a temporary directory for processing.

Snippet

import de.uplanet.io.IOHelper 

File dirTemp = createTemporaryDirectory()

try
{
	
}
finally
{
	IOHelper.deleteFileRecursively(dirTemp)
}	

Class File

Add file to data record

Please note: we recommend using g_dgFile instead of "FileUCHelper".

Add a file to an existing record. With "copyFileToIntrexx(...)" the source file is copied and remains at its storage location. An analog call can be made with "moveFileToIntrexx(...)". In this case, the source file will be moved to Intrexx.

Parameters:
p_ctx - Current processing context (g_context)
p_fileSrc - File to be added to record
p_strFieldGUID - Data field GUID
p_recId - ID of record that the file should be added to
p_bTriggerWorkflow - Should a workflow be triggered that responds to data record changes?

The "p_bTriggerWorkflow" parameter of the "FileUCHelper" class is not implemented so it always has the value "false".

Example

FileUCHelper.copyFileToIntrexx(g_context, fileInput, "0B5CFF839F946923DBB0D92F39BB5D79BEC8D94C", g_record.recId,  false)

Snippet

import de.uplanet.lucy.server.businesslogic.util.FileUCHelper
FileUCHelper.copyFileToIntrexx(g_context, p_fileSrc, p_strFieldGuid, p_recId, p_bTriggerWorkflow) 
		

Class FileUCHelper

Remove file from data record

Please note: we recommend using g_dgFile instead of "FileUCHelper".

Deletes a file from a record.

Parameters:
p_ctx - Current processing context (g_context)
p_strFieldGUID - Data field GUID
p_recId - ID of record where the file should be deleted

Example

FileUCHelper.deleteFileFromIntrexx(g_context, "0B5CFF839F946923DBB0D92F39BB5D79BEC8D94C", g_record.recId)

Snippet

import de.uplanet.lucy.server.businesslogic.util.FileUCHelper
FileUCHelper.deleteFileFromIntrexx(g_context, p_strFieldGuid, p_recId) 
		

Class FileUCHelper

Read text file

Reads the content of a text file with the stated encoding. Do not use for large volumes of data.

Snippet

def fileIn     = new File("<FILE_NAME>")
def strContent = fileIn.getText("UTF-8")

Class File

Read text file line by line

Reads the content of a text file line by line with the stated encoding.

Snippet

def fileIn     = new File("_in.txt")
fileIn.eachLine("UTF-8") {line ->
	//process line
}

Class File

Write to text file

Writes a text output to a file with the stated encoding.

Example

def fileOut  = new File("out.txt")
def strOutput = "This is my output text.\n"

fileOut.withWriter("UTF-8") 
{
		out -> out << strOutput
		out.write(strOutput)
		out.append(strOutput)
}

Snippet

def fileOut = new File("out.txt")

fileOut.withWriter("UTF-8") 
{
out ->	
//write output to  file
}

Class File

Session / User

Name of the current user

Snippet

g_session?.user?.name

Interface IUser

Email address of current user

Snippet

g_session?.user?.emailBiz

Interface IUser

Anonymous session or not?

Snippet

g_session?.anonymous

Class GroovySession

Access the organizational structure

Snippet

g_om.getOrgStructure()

g_om - Details

Users online

Get a list of all non-anonymous, logged-in users.

Snippet

de.uplanet.lucy.server.portalserver.LoggedOnUsers.getLoggedOnUsersDistinct()

Set new password for user

Sets a new password for the stated user.

Snippet

g_om.changePassword(user, password)

Class GroovyOrgBuilder

User management

Create user (basic)

Snippet

g_om.createUser {
	container     = "System"
	name          = "user-${now().withoutFractionalSeconds}" 
	loginName     = "UserU-${now().withoutFractionalSeconds}"
	password      = "secret"
	emailBiz      = "user@example.org"
	description   = "User created with Groovy at ${now().withoutFractionalSeconds}"
}

Create user

Snippet

// provide the copy of an user image (optional)
def fileTemplImage = new File(g_dirWorkflow, "user.jpg")
def fileUserImage  = new File(g_dirWorkflowTmp, "user.jpg")

de.uplanet.io.IOHelper.copyFile(fileUserImage, fileTemplImage)

def user	= g_om.createUser {
container	= "System"
name		= "user-${now().withoutFractionalSeconds}" 
loginName	= "UserU-${now().withoutFractionalSeconds}"
password	= "secret"
emailBiz	= "user@example.org"
description	= "User created with Groovy at ${now().withoutFractionalSeconds}"
nickname	= "dodo"  // this is a custom user field
userImageFile 	= fileUserImage

// provide a list of sets (group, role, dist list, ...) the user should be member of
// allowed are GUIDs, unique names, paths, or org structure set nodes
memberOf 	= ["importantRole", "36B3BFD54A57BE5D1EE51288D920CDA9B20A67A4"]
}

// create a new password and send it to the user's emailBiz address (optional)
g_om.generateAndSendPassword(user, g_defaultLanguage)

Edit existing users

Snippet

def user = g_om.getUser("LOGINNAME", "DOMAIN")

if (user != null)
{
	// provide the copy of a user image (optional)
	def fileTemplImage = new File(g_dirWorkflow, "user.jpg")
	def fileUserImage  = new File(g_dirWorkflowTmp, "user.jpg")
	de.uplanet.io.IOHelper.copyFile(fileUserImage, fileTemplImage)

    // get the GUID list of sets (group, role, dist list, ...) the user is member of
    def membership = user.getDirectMemberSets()
    
    membership.remove("EF16F15EDA8562E19D7CD56BF2E43001F119193C")
    membership.add("36B3BFD54A57BE5D1EE51288D920CDA9B20A67A4")
    
    user.containerGuid = "4B87C2470868AAB57BFB31958D1F73583FB3778E"
    user.name          = "user-${now().withoutFractionalSeconds}"
    user.emailBiz      = "user@example.org"
    user.description   = "User created with Groovy at ${now().withoutFractionalSeconds}"
    user.nickName      = "dodo"  // this is a custom user field
    user.userImageFile = fileUserImage
    
    user.save()
}

Classify GUIDs

Classify GUIDs by

  • User

  • container (organization, organizational unit, ...)

  • set (group, rol, DistList, ...)

  • unclassified GUID

Snippet

def classified = g_om.classifyGuids(/* a list of GUIDs or text that contains GUIDs */)

// do something with the classified GUIDs
classified.users
classified.containers
classified.sets
classified.unclassified

Categories

Date / Time

Snippet

use (groovy.time.TimeCategory)
{
	
}

IValueHolder

Snippet

use (de.uplanet.lucy.server.scripting.groovy.GroovyIntrexxValueHolderCategory)
{
	
}

Class GroovyIntrexxValueHolderCategory

Info

System information

Snippet

def osmbean = java.lang.management.ManagementFactory.operatingSystemMXBean
def sysInfo = """
name                        ${osmbean.name}
version                     ${osmbean.version}
arch                        ${osmbean.arch}
availableProcessors         ${osmbean.availableProcessors}
processCpuTime              ${osmbean.processCpuTime}
systemLoadAverage           ${osmbean.systemLoadAverage}
committedVirtualMemorySize  ${osmbean.committedVirtualMemorySize} bytes
totalPhysicalMemorySize     ${osmbean.totalPhysicalMemorySize} bytes
freePhysicalMemorySize      ${osmbean.freePhysicalMemorySize} bytes
totalSwapSpaceSize          ${osmbean.totalSwapSpaceSize} bytes
freeSwapSpaceSize           ${osmbean.freeSwapSpaceSize} bytes"""

g_log.info(sysInfo)

Intrexx version

Returns the Intrexx installation version.

Snippet

de.uplanet.lucy.VERSION.CURRENT.toFormattedString()

Class Version

Error handling and debugging

Stacktrace as string

Snippet

getStackTraceString()

Groovy context

Snippet

def dumpBinding = {
	def sbuf = new StringBuilder()

	sbuf << "Dump the Groovy binding:\n"

	binding.variables.each { k, v ->
		if (v && v.metaClass && v.metaClass.respondsTo(v, "dump"))
			sbuf << "${k} = ${v.dump()}\n"
		else
			sbuf << "${k} = ${v?.toString()}\n"
	}

	sbuf.toString()
}

g_log.info(dumpBinding())

Define an error handler for a script

Usable in

  • Groovy page

  • Action and rendering handlers

Snippet

onError = { exception, err ->	
	err.title = ""
	err.description = "Insert your description here. ${exception.message}"
}

Groovy server scripts

JSON response

Please note that a permissions check (IxAccessController) is required before any action that is triggered by a user.

Snippet

response.json()

// define an error handler
response.onError = 
{
e, err ->	
    //err.type = "default"
    // either title/description, ...
    err.title = "my error"
    err.description = e.message
    err.showEmbedded = true
    // ... or a redirect
    // err.redirectUrl = "https://www.example.org/"
    err.redirectDelay = 1500 // milliseconds
}

// check permissions
g_permissions.check 
{
    // application("${application.guid}": "access")
    // dataGroup("<data group GUID>": "read", "<another data group GUID>": "write,create")
}

// create some JSON content
writeJSON("person": [
    givenName: "Donald",
    lastName: "Duck",
    age: 78,
    nephews: ["Huey", "Dewey", "Louie"]
])
		

Possible variations of the script above

Closure without or with exactly one parameter

If the closure declares a parameter, the exception that occurred is transferred to the closure in the first parameter (e).

Snippet

// define an error handler
response.onError = {e ->
	writeJSON("error": "Something bad happened.")
}

Closure with two parameters

The exception that occurred is transferred to the closure in the first parameter (e) and a ErrorResponseData object is transferred in the second parameter (err). The ErrorResponseData object can be configured in the closure according to the respective requirements.

Snippet

// define an error handler
response.onError = {e, err ->
	//err.type = "default"
	// either title/description, ...
	err.title = "my error"
	err.description = e.message
	err.showEmbedded = true
	// ... or a redirect
	// err.redirectUrl = "https://www.example.org/"
	// err.redirectDelay = 1500 // milliseconds
}

With a string

The stated string is sent to the client in the response body.

Snippet

response.onError = '{"error": "Something bad happened."}'

Assign another object

In a JSON response scenario, an attempt is made to generate JSON from the object. If the response is not JSON, an attempt is made to output the object in a suitable manner as text.

Snippet

response.onError = [
	"error": "Something bad happened.",
	"solace": "But things could be worse."
]

Velocity

Create text from a Velocity template

Snippet

import de.uplanet.lucy.server.scripting.velocity.VelocityContextUtil
import org.apache.velocity.app.Velocity

def fileVm = new File(g_dirWorkflow, "") // the Velocity input file
def vc     = VelocityContextUtil.createDefaultContext(g_context)

// add additional variables to the Velocity context
// vc.put("PreparedQuery", g_dbQuery)
// vc.put("variableName", variableValue)

def template = Velocity.getTemplate(fileVm.path)
def writer   = new StringWriter(4096) // 4 KiB initial buffer

template.merge(vc, writer)

g_log.info(writer.toString())

Create file from a Velocity template

For security reasons, Velocity files can only be executed if they are stored in one of the following subfolders:

  • internal/system/vm

  • internal/layout/vm

  • internal/application/vm/

  • internal/application/resource

  • internal/workflow/<GUID>/velocity/

Request-Variable

g_request.get(...)

Snippet

g_request.get("")

Class GroovyServerBridgeRequest

rq_Lang

Returns the language the logged-in user is currently using.

Snippet

rq_Lang

REMOTE_ADDR

IP address of the client computer.

Snippet

REMOTE_ADDR

SERVER_PORT

Snippet

SERVER_PORT

Snippet

HTTP_HOST

Snippet

HTTP_HOST

HTTP_REFERER

Snippet

HTTP_REFERER

Snippet

HTTP_COOKIE

HTTP_USER_AGENT

Snippet

HTTP_USER_AGENT

SCHEME

HTTP or HTTPS

Snippet

SCHEME

Images

Scale image

Supported formats are PNG, JPEG (JPG), and BMP.

Snippet

import de.uplanet.lucy.server.scripting.groovy.ImageHelper

// Parameters: inputFile, outputFile, format?, width?, height?, maxWidth?, 
// maxHeight?, scaleX?, scaleY?, shrinkOnly?, rotate?, crop?
ImageHelper.scaleImage(inputFile: , outputFile: <OUTPUT_FILE>)

Class ImageHelper

Determine the size of an image

A file object or a path as a character string can be transferred as parameters.

Snippet

import de.uplanet.lucy.server.scripting.groovy.ImageHelper

def (x, y) = ImageHelper.getImageSize()
		

Class ImageHelper

Iterate over image metadata

Here is an example of metadata extraction.

Snippet

import de.uplanet.lucy.server.scripting.groovy.ImageHelper

def file = ImageHelper.getImageMetaData(file).each { 
    tag, value ->	println("$tag -> $value")
}
		

Class ImageHelper

Logging

Write info to the portal log

Writes an INFO log entry to the portal log file (portal.log). This method can be used if the log file of the current processing context is not portal.log, but portal.log should be used.

Snippet

g_syslog.info("")

Class GroovyLogger

Write info to log file

Writes an INFO entry to the log file that belongs to the execution context of the script.

Snippet

g_log.info("")

Class GroovyLogger

Write warning to log file

Writes an WARN log entry to the portal log file (portal.log). This method can be used if the log file of the current processing context is not the portal.log, but portal.log should be used.

Snippet

g_syslog.warn("")

Class GroovyLogger

Write warning to log file

Writes a WARN entry to the log file that belongs to the execution context of the script.

Snippet

g_log.warn("")

Class GroovyLogger

Write error to log file

Writes an ERROR log entry to the portal log file (portal.log). This method can be used if the log file of the current processing context is not the portal.log, but portal.log should be used.

Snippet

g_syslog.error("")

Class GroovyLogger

Write error to log file

Writes an ERROR entry to the log file that belongs to the execution context of the script.

Snippet

g_log.error("")

Class GroovyLogger

Read the statistics logs

Snippet

import de.uplanet.lucy.server.monitor.log.GroovyLogReader

// flush queued log entries to disk
GroovyLogReader.flushLogQueue()

// collect the log files
def logFiles = []

new File("internal/statistics").eachFile {
	if (!it.name.startsWith(".")) // TODO check additional criteria
		logFiles << it
}

// read the selected log files
logFiles.each { file ->
	GroovyLogReader.readLog(file) { entry ->
		// TODO do something with the entry
		println("Time in millis = ${entry.time}, targetGuid = ${entry.targetGuid}")
	}
}

Connector for Microsoft Exchange

Current Exchange connection

Returns the current connection to Microsoft Exchange.

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil

def connEx = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)

Class ExchangeConnectionUtil

Mailbox name of the current Exchange user

Returns the mailbox name of the current Exchange user.

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil
import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils

def connEx      = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def mailboxUtil = ExchangeUtils.getMailboxUtil(connEx)

def strMailboxName = mailboxUtil.getImpersonateUserAccount(g_context.impersonateUserGuid).exchangeMailbox

Class ExchangeUserMailboxInfo

Save email locally as an EML file

Saves an email locally as an EML file. Alternatively, saveMessageAsMSG can be used to save an email as a MSG file.

Parameters:

  • strMessageId - ID of message to be saved

  • fileMail - File object to save the message

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils
import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil

def connEx      = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def messageUtil = ExchangeUtils.getMessageUtil(connEx)

messageUtil.saveMessageAsEML(strMessageId, fileMail)

Interface IExchangeMessageUtil

Save email attachments

Save attachments of an email defined by strMessageId.

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils
import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil

def connEx      = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def itemUtil    = ExchangeUtils.getItemUtil(connEx)
def attachments = itemUtil.getAttachments(strMessageId)

attachments.each{ item ->
	def attachment = new File(g_dirWorkflowTmp, item.displayName)
	itemUtil.saveAttachment(item, attachment)
}

Interface IExchangeItemUtil

Set the out of office message

Writes the out of office message and sets its status to active. Attention: The text is set for internal and external out of office messages.

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils
import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil

def connEx      = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def mailboxUtil = ExchangeUtils.getMailboxUtil(connEx)

mailboxUtil.setOutOfOfficeMessage("Out of office till 2010/31/12")
mailboxUtil.setOutOfOffice(true)

Interface IExchangeMailboxUtil

Get folder information

Gets information about a folder from the Exchange account.

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils
import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil

def connEx      = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def mailboxUtil = ExchangeUtils.getMailboxUtil(connEx)
def folderInfo  = mailboxUtil.getFolderInfoByHref(mailboxUtil.getInboxFolderHref())

Interface IFolderInfo

Create folder

Create an Exchange folder (in this example in the default inbox folder)

Parameters:

  • Name of the parent folder

  • Name of the new folder

  • Exchange content class

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils
import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil

def connEx         = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def mailboxUtil    = ExchangeUtils.getMailboxUtil(connEx)
def strInboxFolder = mailboxUtil.getInboxFolderHref()

mailboxUtil.createFolder(strInboxFolder, "myFolder", "urn:content-classes:mailfolder")

Interface IExchangeMailboxUtil

Add attachment to an element

Adds an attachment to an existing item (e.g. an appointment).

Parameters:

  • strItemId - ID of item that the file should be attached to

  • fileAttach - File to be attached

  • strFileName - Name of the attachment

  • strMimeType - The attachment's mime type. If null, application/octet-stream will be used

  • bIsContactPhoto - True, if an image file should be used as contact photo

  • bDeleteAfter - True, if the file should be deleted after being attached

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils

def connEx      = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def itemUtil    = ExchangeUtils.getItemUtil(connEx)
def strFileName = "myAttachment.txt"
def strMimeType = "text/plain"
def fileAttach  = new File(strFileName)

itemUtil.addAttachmentToItem(strItemId, fileAttach, strFileName, strMimeType, bIsContactPhoto, bDeleteAfter)

Interface IExchangeItemUtil

Create an Exchange appointment

Creates an appointment for the current user.

Parameters:

  • dtStartDate - Start date of the appointment

  • dtEndDate - End date of the appointment

  • strSubject - Title of the appointment

  • strBody - Description of the appointment

If additional properties are set or updated with set()-methods after creating the appointment, they have to be saved with appointment.save() afterwards.

Example

def appointment = aptUtil.createNewAppointment(dtStartDate, dtEndDate, strSubject, strBody)

appointment.setLocation("Konferenzraum")
appointment.save()

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil
import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils

def connEx  = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def aptUtil = ExchangeUtils.getAppointmentUtil(connEx)

def appointment = aptUtil.createNewAppointment(dtStartDate, dtEndDate, strSubject, strBody)

Interface IExchangeAppointmentUtil

Create an Exchange contact

Creates a new contact for the current user.

Parameters:

  • strLastName - Last name of the contact

  • strFirstName - First name of the contact

  • strMail - Email address of the contact

  • strMailbox - The user's mailbox that the contact should be added to. If null, the current user's mailbox is used.

If additional properties are set or updated with set()-methods after creating the contact, they have to be saved with contact.save() afterwards.

Example

def contact = contactUtil.createNewContact("Doe", "John", "john.doe@example.org", null)

contact.setJobTitle("Developer")
contact.save()

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil
import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils

def connEx      = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def contactUtil = ExchangeUtils.getContactUtil(connEx)

def contact = contactUtil.createNewContact(strLastName, strFirstName, strMail, strMailbox)

Interface IExchangeContactUtil

Create and end Exchange email

Creates a new email for the current Exchange user.

Parameters:

  • strFrom - Sender address

  • strTo - Recipient address

  • strSubject - Subject

  • strBody - Message text

If additional properties are set or updated with set()-methods after creating the message, they have to be saved with message.save() afterwards.

Example

def message = msgUtil.createNewDraft("sender@example.org", "recipient@example.org", "Example subject", "Example text")


message.setCc("cc_recipient@example.org")
message.save()
message.send()

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil
import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils

def connEx  = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def msgUtil = ExchangeUtils.getMessageUtil(connEx)

def message = msgUtil.createNewDraft(strSender, strRecipient, strSubject, strBody)

Interface IExchangeMessageUtil

Create an Exchange note

Creates a note for the current user.

Parameters:

  • strText - Text of the note

  • strMailBox - The user's mailbox that the contact should be added to. If null, the current user's mailbox is used.

Example

def noteUtil = ExchangeUtils.getNoteUtil(connEx)
def note = noteUtil.createNewNote("My note", null)

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil
import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils

def connEx   = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def noteUtil = ExchangeUtils.getNoteUtil(connEx)

def note = noteUtil.createNewNote(strText, strMailBox)

Interface IExchangeNoteUtil

Create an Exchange task

Creates a task for the current user.

Parameters:

  • dtStart - The task start date

  • dtDue - The task due date

  • strSubject - The task subject

  • strMailBox - The user's mailbox that the note should be added to. If null, the current user's mailbox is used.

Example

def taskUtil = ExchangeUtils.getTaskUtil(connEx)

def dtStart, dtDue, reminder

use (groovy.time.TimeCategory)
{
	dtStart   = new Date() + 1.day
	dtStart   = dtStart.clearTime()
	dtDue    = dtStart + 5.days
	reminder = dtDue - 12.hours
}

def task = taskUtil.createNewTask(dtStart, dtDue, "Task subject", null)

task.setPercentComplete(25.0)
task.setUserDefinedFieldValue("ReminderTime", VH.getValueHolder(reminder))
task.setUserDefinedFieldValue("ReminderSet",  VH.getValueHolder(true))

task.save()

Snippet

import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeConnectionUtil
import de.uplanet.lucy.server.businesslogic.exchange.util.ExchangeUtils

def connEx   = ExchangeConnectionUtil.getConnectionForWorkflowAction(g_context)
def taskUtil = ExchangeUtils.getTaskUtil(connEx)

def task = taskUtil.createNewTask(dtStart, dtDue, "Task subject", null)

Interface IExchangeTaskUtil

Portlets

Only show portlet if table contains data records

The following script means that the portlet is only displayed if the table contains data records; the "Restrict display of the portlet on the web by Groovy script" setting must be activated. The script can also be used if the "Restrict selection of the portlet on the web by Groovy script" is activated. In this case, the portlet will no longer be listed under "Portlets and applications" on the portlet settings page and cannot be added to the portal page if the table does not contain any records.

Snippet

g_dataCollection.getDataRange("768A3C783F2BC9FD7EF20B1979FD3B27498779E2").getNumberOfRecords() > 0

Tips & Tricks - Filter portlets with Groovy

Restrict portlets in the portlet container

To restrict portlets in the portlet container, a list with portlet objects must be returned. You can retrieve all available portlet objects with "g_portletPool". In this example, only the portlet with the GUID entered instead of the placeholder would be available.

Snippet

def portletsAus = []

for(portlet in g_portletPool){
	if(portlet.getPageGuid() == "<GUID>)"{
			portletsAus.add(portlet) 
	}
}
return portletsAus 

Class GroovyPortlet

Control the display with a Boolean value

By returning a Boolean value, you can control whether a portlet should be displayed or not, for example in the portlet properties:

Snippet

def isok = "<check if a portlet shall be displayed>"
if( isok)
	return true
else
	return false

Class GroovyPortlet

WebSockets

Sending a text message

Example

import de.uplanet.lucy.server.websocket.groovy.GroovyWebSocketTopic
GroovyWebSocketTopic.sendTextMessage("D00F000000000000000000000000000000000000", "Hello world!")

Snippet

import de.uplanet.lucy.server.websocket.groovy.GroovyWebSocketTopic
GroovyWebSocketTopic.sendTextMessage("<topicGUID>", "<string>")

Class GroovyWebSocketTopic

Sending a JSON message

Example

import de.uplanet.lucy.server.websocket.groovy.GroovyWebSocketTopic

def msg = [
    seq: 1,
    greet: "Hello world!"
]

GroovyWebSocketTopic.sendJsonMessage("D00F000000000000000000000000000000000000", msg)

Snippet

import de.uplanet.lucy.server.websocket.groovy.GroovyWebSocketTopic

def msg = [
	seq: 1,
	greet: "<string>"
]

GroovyWebSocketTopic.sendJsonMessage(${cursor}"<topicGUID>", msg)

Class GroovyWebSocketTopic

Check for an interrupt request

checkInterrupted()

Checks whether either

  • the thread that performs the process has received an interrupt request from another thread or

  • the timeout defined for the process has been exceeded.

Use this call in scripts that should behave cooperatively in such cases.

Snippet

checkInterrupted()

Class CheckInterruptedClosure

Automatic logout of implicitly generated sessions

If a Groovy endpoint is called and the client does not send a valid session ID, then an anonymous session is implicitly generated on the server. The following script allows you to prevent these sessions from staying on the server until the timeout of the anonymous session. The criterion for the automatic logout is that the client has not sent a co_SId session cookie.

Snippet

import de.uplanet.server.transaction.TransactionManager

// if the client did not send a session cookie we logout
// the session after the current transaction has finished
if (!g_request.get('co_SId'))
	TransactionManager.addAfterCommitAction {g_session.logout()}

Start a scheduler job

Input parameters: ID or GUID of the job. The parameters "testParam" and "greeting" from the following snippet are available in the SharedState in the started timer process.

Snippet

import de.uplanet.lucy.server.scheduler.JobStarter
JobStarter.startJob("B39F3AA1C06E56FD06538F92F46C075333F97F68", [testParam: true, greeting: ' Hello world!'])

Tips & Tricks - Start processes

Run an external program

Runs an external program. Click here for more information.

Snippet

def pOut = new StringBuffer()
def pErr = new StringBuffer()
def proc = [""].execute()

proc.consumeProcessOutput(pOut, pErr)
proc.waitForOrKill(10000) // 10 seconds

if (proc.exitValue() == 0)
{
	// success
	// ...
}
else
{
	// an error occurred
	g_log.error(pErr.toString())
}

Class Process

Create a new GUID

Generates a new GUID.

Snippet

newGuid()

Class NewGuidClosure

Check GUID

Checks whether a specified string is a GUID in Intrexx terms. If the transferred value is null, the method returns false.

Example:

def valueToCheck = 'DAF7CECF66481FCABE50E529828116EAFE906962'
if (Guid.isStringRepresentation(valueToCheck))
{
    //valid GUID
}

Snippet

Guid.isStringRepresentation('<GUID>')

Class Guid

Create a ValueHolder

Creates a ValueHolder for a simple data type. If null is transferred, a NullValueHolder will be created. Its value is null, and hasValue() is false.

Snippet

vh()

Parse GUIDs

Parse GUIDs from textual input. Multiple parameters are possible.

Snippet

parseGuids()

Determining the time zone of the portal

Here you find script for determining the default time zone, which is set in the portal properties in the regional settings.

Snippet

import  de.uplanet.lucy.server.DefaultTimeZone
def tz = DefaultTimeZone.get()

Class DefaultTimeZone

Determine start time and uptime of the portal

Snippet

g_portal.getStartTime()
g_portal.getUptimeMillis()

Class GroovyPortalInfo

Template - Groovy API for short links

Criteria for matching short links with the configured short link rule:

Match criteria

1.) equal static path prefix

2.) equal number of path components or path components + variables and equal number of slashes

3.) Path components which are not variable must be equal

For variable path components, the variables are assigned the values of the path components.

Creating target URLs

Target URLs can be absolute or relative to the root directory of the website. In the first instance, any number of targets can be given. In the second instance, the website is assumed to be the target, which is requested in the website browser.

The variables allocated during matching can be used in the target URL and as a part of the path and even the query string. Query string parameters which are in the input URL but not the configured target URL are saved to the output URL.

Examples


import de.uplanet.lucy.server.urlredirect.scripting.groovy.GroovyRedirectRules

//----------------------------------
// create a new empty configuration
//----------------------------------

def rules = GroovyRedirectRules.createNew()
assert rules.isEmpty() // no rules
assert rules.size() == 0 // no rules


//---------------------------------------
// create and append some redirect rules
//---------------------------------------

def rule1 = rules.createNewRule('/from/path/1', '/to/path1')
rules << rule1 // append it
	assert rules.size() == 1

	def rule2 = rules.createNewRule('/from/path/2', '/to/path2')
	rules << rule2
	assert rules.size() == 2

	def rule3 = rules.createNewRule(
		fromUrl: '/search/${term}',
		toUrl:   'https://www.google.de/search?q=intrexx+${term}')
	rules << rule3
	assert rules.size() == 3

	def rule4 = rules.createNewRule(
		fromUrl: '/customer/${custNo}',
		toUrl:   '/foo/?customer=${custNo}',
		appGuid: 'DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF')
	rules << rule4
	assert rules.size() == 4

	def rule5 = rules.createNewRule(
		fromUrl: '/invoice/${invoiceNo}',
		toUrl:   '/bar/?invoice=${invoiceNo}',
		appGuid: 'DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF')
	rules << rule5
	assert rules.size() == 5

	// check if a rule is in the rules list
	assert rules.contains(rule1) == true
	assert rules[1] == rule2

	// save the newly created redirect rules; this overwites internal/cfg/urlredirect.cfg
	// and thus deletes all existing rules defined therein
	rules.save()

	rules = null // no reference to the rules anymore


	//-------------------------------------------------------
	// load existing rules from internal/cfg/urlredirect.cfg
	//-------------------------------------------------------

	rules = GroovyRedirectRules.load()
	assert rules.size() == 5

	// list the from URLs
	def froms = rules*.fromUrl
	assert froms == [
		'/from/path/1',
		'/from/path/2',
		'/search/${term}',
		'/customer/${custNo}',
		'/invoice/${invoiceNo}']

	// find a certain rule
	def rule = rules.find {it.fromUrl == '/customer/${custNo}'}
	assert rules.indexOf(rule) == 3
	assert rule.fromUrl == '/customer/${custNo}'
	assert rule.toUrl   == '/foo/?customer=${custNo}'

	// modify the rule
	rule.toUrl = '/bar/?customer=${custNo}'
	assert rule.toUrl   == '/bar/?customer=${custNo}'

	// find all rules that belong to application with
	// GUID DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF
	def appRules = rules.findAll {it.appGuid == 'DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF'}
	assert appRules.size() == 2

	// remove these rules
	rules.removeAll(appRules)
	assert rules.size() == 3

Snippet

import de.uplanet.lucy.server.urlredirect.scripting.groovy.GroovyRedirectRules
def rules = GroovyRedirectRules.load()
// do something with the redirect rules
rules.save()

Class GroovyRedirectRules