It is possible to enter an ampersand (&) in a String via Clarity and the stored value in the database will be '&'. For example, entering 'A&B' will store 'A&B' in the database.
Similarly, when using the REST API, the same value will also be stored as 'A&B'.
However, doing the same REST API calls via a GEL script will always escape the characters stored in the database to 'A&B'.
Steps to Reproduce:
Sample script:
(Pre-requisites - adjust the script if any pre-requisite is changed):
user
', with all rightspassword
'<gel:script xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wss="http://www.boomi.com/connector/wss" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xog="http://www.niku.com/xog" xmlns:x="jelly:org.apache.commons.jelly.tags.xml.XMLTagLibrary" xmlns:util="jelly:util" xmlns:sql="jelly:sql" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:jelly="jelly:core" xmlns:nikuq="http://www.niku.com/xog/Query" xmlns:gel="jelly:com.niku.union.gel.GELTagLibrary" xmlns:file="jelly:com.niku.union.gel.FileTagLibrary" xmlns:core="jelly:core">
<!--***************************************Get the session from the system Start ***********************************-->
<gel:parameter var="gel_host_user" default="user"/>
<gel:parameter var="gel_host_pass" default="password"/>
<gel:setDataSource dbId="niku"/>
<!--Set parameter here End -->
<!--***************************************Get the session from the system End ***********************************-->
<!-- Generate SessionID -->
<core:new className="com.niku.union.security.DefaultSecurityIdentifier" var="secId"/>
<core:invokeStatic var="userSessionCtrl" className="com.niku.union.security.UserSessionControllerFactory" method="getInstance"/>
<core:set var="secId" value="${userSessionCtrl.init(gel_host_user, secId)}"/>
<core:set var="sessionID" value="${secId.getSessionId()}"/>
<core:choose>
<core:when test="${sessionID == null}">
<gel:log level="ERROR">Cannot login to Clarity XOG. Check username.</gel:log>
</core:when>
<core:otherwise>
<gel:log>SessionID: ${sessionID}</gel:log>
</core:otherwise>
</core:choose>
<!--core:invoke method="setHeader" on="${patch}"> <core:arg type="java.lang.String" value="Cookie"/>
<core:arg type="java.lang.String" value="${v_Cookie}"/> </core:invoke-->
<core:new var="patch" className="org.apache.http.client.methods.HttpPatch">
<core:arg value="https://<hostname>/ppm/rest/v1/projects/<instance>" type="java.lang.String"/>
</core:new>
<core:invoke on="${patch}" method="setHeader">
<core:arg value="Authorization" type="java.lang.String"/>
<core:arg value="Basic dXNlcjpwYXNzd29yZA==" type="java.lang.String"/>
</core:invoke>
<core:invoke on="${patch}" method="setHeader">
<core:arg value="Content-Type" type="java.lang.String"/>
<core:arg value="application/json" type="java.lang.String"/>
</core:invoke>
<core:set var="createProject" escapeText="false"><![CDATA[{"z_mystring":"A&B"}]]></core:set>
<!-- <core:set var="createProject" escapeText="false">{"code": "${row.CODE}", "name": "${row.NAME}", "description":"${row.DESCRIPTION}" }</core:set> -->
<core:new var="entity" className="org.apache.http.entity.StringEntity">
<core:arg value="${createProject}" type="java.lang.String"/>
</core:new>
<gel:log>entity: ${entity}</gel:log>
<core:invoke on="${patch}" method="setEntity">
<core:arg value="${entity}" type="org.apache.http.entity.StringEntity"/>
</core:invoke>
<gel:log>patch: ${patch}</gel:log>
<core:invokeStatic var="httpclient" className="org.apache.http.impl.client.HttpClients" method="createDefault"/>
<core:invoke var="response" on="${httpclient}" method="execute">
<core:arg value="${patch}" type="org.apache.http.client.methods.HttpPatch"/>
</core:invoke>
<gel:log>response: ${response}</gel:log>
<core:invoke var="entityResponse" on="${response}" method="getEntity"/>
<core:invoke var="ResponseStatus" on="${response}" method="getStatusLine"/>
<gel:log>ResponseStatus getProtocolVersion: ${ResponseStatus.getProtocolVersion()}</gel:log>
<gel:log>ResponseStatus getReasonPhrase: ${ResponseStatus.getReasonPhrase()}</gel:log>
<gel:log>ResponseStatus getStatusCode: ${ResponseStatus.getStatusCode()}</gel:log>
<gel:log>entityResponse: ${entityResponse}</gel:log>
<core:set var="void" value="${response.close()}"/>
<gel:log>exception::${exception}</gel:log>
</gel:script>
Expected Results: Value stored is 'A&B' - same as when using Clarity or the REST API without a GEL script.
Actual Results: Value stored is 'A&B'.
Any Clarity supported version.
According to the Expected Results, the script is not correct:
<core:set var="createProject" escapeText="false"><![CDATA[{"z_mystring":"A&B"}]]></core:set>
The way the createProject
variable is declared, the variable's content will get encoded (replacing &
with &
).
To avoid the encoding, the variable needs to be declared as follows:
<core:set var="createProject" encode="0"><![CDATA[{"z_mystring":"A&B"}]]></core:set>
This tag sets a variable from the result of an expression.
encode
When set to:
Use this only if this tag is specified with no value so that the text body of this tag can be used as the body.
Type: Boolean