Introduction

The XTEND server does not have any Scripting function to execute JavaScript scripts on the server to dynamically build HTML pages the same way as a PHP script.

It is recommended to use scripting when the HTML code to generate cannot be dealt with through token insertion.

Server scripts can also be executed by AJAX requests sent from the browser.

Script insertion

The script must be inserted in the HTML page inside the <script> tag where the HTML code needs to be generated.

To identify a server script, a field token must be placed in the tag: <script adx="MyTokenField"></script>.

The following example shows a page with the following text Text generated by a server script.

<html><body>
<script adx="TestScript1">
    print("<b>Text generated by a server script</b>");
</script>
</body></html>

Use of libraries

The XTEND scripting engine is used to include libraries (JavaScript file) in the code via the following instruction: #include 'pathLib'.

pathLib is the access path of the library file respective to the root directory of server scripts defined in the setup record of the site.

<script adx="TestScript2">
    #include 'libs\xtdWsvc.js''
</script>

Library provided in standard

Scripting libraries can be found in the following directory:

WebTools\TOOLS\XTEND\HTMRSRC\LIB\SCRIPTING
WebTools is the Tools installation directory of X3WEB server

xtdPrototype.js

This library is an adaptation of the prototype.js library version 1.6.0.2 minus functions of graphic objects manipulation (DOM).

The developer can use a range of functions and classes which are very useful, such as class management with inheritance, grid management and HashMaps...

xtdWsvc.js

Provides utility functions for the call to XTEND web services and the control of JSON data (setups and result).

In order to use these libraries, the user must copy them in the site server scripts directory et include them in the JavaScript code via the following instruction: #include.

Programming

Building the HTML

The principle of scripting consists in building dynamically HTML text by executing JavaScript instructions.

The print() function is used to send HTML to the browser.

Actually, the print function is used to fill a text buffer that will be inserted, after the execution of the code, in the HTML page in place of the script.

Access the XTEND engine context

The global scope object XTD_CTX gives access to the XTEND engine context through a range of methods.

//Information on user account
public boolean userLogged();
public String userCode();
public String userProfile();
public String userLang();
//Returns a section
//The section token should be inserted in the page to declare it
//without adding children<!adx="monBlock"><!adx="monBlock">
public IXtdJsTokenBlock getTokenBlock(String aBlockId);
//Returns an Action or Session entity
public IXtdJsActEntity getActionEntity(String aId);
//Resends the URL of current servlet in secured mode (https) or not
public String getServletUrl(boolean aSecured);
//Returns the complete URL to access a page
public String getPageUrl(String aPage);
//Returns the complete URL to execute a dynamic link in GET method
public String getDlkUrl(String aDynLink);
//Returns the tag <a href='' onclick='xtdDoDlk(..)'> associated with the dynamic link
//The tag </a> must be added in scripting
public String getDlkAnchor(String aDynLink,String aClass);
//Returns the input tag <input type='button' onclick='xtdDoDlk(..)'>
//associated to the dynamic link
public String getDlkButton(String aDynLink,String aValue,String aClass);
//Returns with the JS functionjs generated by Xtend in the management of
//dynamic links
public String getDlkOnclick(String aDynLink, boolean aIsInputTag);
public String getDlkOnSubmit(String aDynLink);
//Used to take into account the Javascript of input tags such as checkbox
//used in the actions
//Xtend generated an hidden input for unchecked checkboxes
public void checkBoxAdd(String aInputName);
public void checkBoxAdd(String aInputName,String aUncheckedValue);

For instance

This is an example where the LOGIN sub-program returns a "SITES" field which is stored in the session (account information and which contains a list of sites authorized for the user.

The list of sites is returned as a query string such as Key1=value&Key2=value.

The script aims at creating a select tag from the SITES field data.

This type of operation cannot be done via a token. A server script is needed.
The decoding operation can also be done via a customer JavaScript script but there is no access to the data context of the XTEND session.

Script

<div id="testscript">
<script adx="UserSites">
//Tests if the user is signed
if (XTD_CTX.userLogged())
{
    //Utilities library
    #include 'libs\xtdWsvc.js'
   
    //Reads the SITES field which contains the query string
    //-> "site1=S1&site2=S2&site3=S3"
    var wQs=new String(XTD_CTX.getField("SITES"));
   
    //Parses the String to create a JavaScript object (see prototype.js)
    //-> {site1:"S1",site2:"S2",site3:"S3"}
    var wObj=wQs.parseQuery();
   
    //Utility object to build the HTML that will be inserted in the page
    //-> Librairy xtdWsvc.js
    var wHtml=new XTENDWSVC.classHTMLBuffer();
    //The HTML is a select tag
    wHtml.select(["value","SITES","class","xtendInput"]);
   
    //Grid of values (see prototype.js)
    var wValues=Object.values(wObj);
    //Key grid (see prototype.js)
    var wKeys=Object.keys(wObj);
    //Addition of options
    for (i=0;i<wKeys.length;i++)
        wHtml.option(wValues[i],wKeys[i]);
    wHtml.endSelect();
   
    //Writing of the HTML answer
    print(wHtml.html());
</script>
</div>

Result

Result with the SITES field value:
Site Grenoble=FCYGRE&Site Paris=FCYPAR&Site Lyon=FCYLY&Site Rouen=FCYROU

<div id="testscript">
    <select class="xtendInput" value="SITES">
        <option value="FCYGRE">Site Grenoble</option>
        <option value="FCYLY">Site Lyon</option>
        <option value="FCYROU">Site Rouen</option>
        <option value="FCYPAR">Site Paris</option>
    </select>
</div>

Access the sections of the page

The XTD_CTX.getTokenBlock(BlockID) function returns a IXtdJsTokenBlock interface which is used to access methods and proprieties of a section token inserted in the HTML page.

The section token should be inserted in the page to declare it without necessarily adding any child <!adx="BlockId"><!adx="BlockId">

Interface

public interface IXtdJsTokenBlock extends IXtdJsData
{
    // Retuns an iterator on the section lines
    public IXtdJsDataIterator getLines();
}

The IXtdJsTokenBlock interface points to the section and is used to access section fields.

The IXtdJsDataIterator interface is used to perform an iteration on the section lines.

For instance

<Html><body>
<!--Déclaration du bloc-->
<!adx="MyBlock"><!adx="MyBlock">
<!--Affichage des lignes du bloc-->
<script adx="TestScript">
    var wBlock=XTD_CTX.getTokenBlock("MyBlock");
    var wLines=wBlock.getLines();
    print ("Nombre de page="+wBlock.getField("APAGENB")+"<br>");
    print ("Nombre de lignes="+wBlock.getField("ABLKNBLINES")+"<br>");
    while(wLines.hasNext()){
        var wLine=wLines.next();
        print("<tr>");
        print("<td>"+wLine.getField("PRIX")+"</td>");
        print("<td>"+wLine.getField("STOCK")+"</td>");
        print("</tr>");
    }
</script>
</body></html>

Access action entities

The XTD_CTX.getActionEntity(EntityID) function returns a IXtdJsActEntity interface used to access methods and properties of the entity.

Only entities such as session or action can be accessed directly (without the intermediary of a section token) because they are stored in the user session (persistent).

Data access entities cannot be accessed directly but only via a section token.

Interface

public interface IXtdJsActEntity
{
    // Returns the entity code
    public String getCode();
    // Returns an iterator on entities
    public IXtdJsDataIterator<IXtdJsActEntityData> getIterator();
    // Adds an entity and returns the interface on this entity
    // --> Fields should then be added
    public IXtdJsActEntityData addData();
    // Deletes the ID entity aId
    public IXtdJsActEntityData removeData(String aId);
    // Returns the ID entity aId
    public IXtdJsActEntityData getData(String aId);
}
public interface IXtdJsActEntityData extends IXtdJsData
{
    //Data from an entity which adds the getID method
    //to the IXtdJsData standard interface
    public String getId();  
}

The IXtdJsTokenBlock interface points to the section and is used to access section fields.

The IXtdJsDataIterator interface is used to perform an iteration on the section lines.

For instance

<Html><body>
<!--Déclaration du bloc-->
<!adx="MyBlock"><!adx="MyBlock">
<!--Affichage des lignes du bloc-->
<script adx="TestScript">
    var wEntities=XTD_CTX.getActionEntity("XTDLOGINV");
    var wIterator=wEntities.getIterator();
    print("Size="+wIterator.size() + " - Code="+ wEntities.getCode());         
    print("<table><br>");
    while(wIterator.hasNext()){
        var wLine=wIterator.next();
        print("<tr>");
        print("<td>"+wLine.getId()+"</td>");
        print("<td>"+wLine.getField("INVADR1")+"</td>");
        print("<td>"+wLine.getField("INVCITY")+"</td>");
        print("</tr>");
    }
    print("</table>");
</script>
</body></html>

Iteration on a section line or action entities

The IXtdJsDataIterator interface is used to perform an iteration on the section lines or action entities.

Interface

public interface IXtdJsDataIterator
{
    // Returns the number of data
    public int size();
    // True if the iterator contains data
    public boolean hasNext();
    // Returns the current data and increment
    public IXtdJsData next();
    // Returns the iterator in JSON format
    public String toJSON();
}

For instance

var wEntities=XTD_CTX.getActionEntity("XTDLOGINV");
var wIterator=wEntities.getIterator();
while(wIterator.hasNext()){
        var wLine=wIterator.next();
        print("<tr>");
        print("<td>"+wLine.getId()+"</td>");
        print("<td>"+wLine.getField("INVADR1")+"</td>");
        print("</tr>");
}

Iteration on a section line or action entities

Interface

public interface IXtdJsDataIterator<ClassData extends IXtdJsData>
{
    public boolean hasNext();
    public ClassData next();
    public String toJSON();
}
public interface IXtdJsData
{
    public void removeField(String aFieldName);
    public void setField(String aFieldName, String aValue);
    public String getField(String aFieldName);
    public String getField(String aFieldName, boolean aFormated);
    public String getField(String aFieldName, String aFormat);
    public String getMenuLabel(String aFieldName);
    public String getFieldJSON(String aFieldName);
    public String toJSON();  
}
public interface IXtdJsTokenBlock extends IXtdJsData
{
    public IXtdJsDataIterator getLines();
}

Access to fields of a section or entity line

The IXtdJsData interface is used to access fields of a section or an entity.

Interface

public interface IXtdJsData
{
    // Deletes the aFieldName field
    public void removeField(String aFieldName);
    // Valuates the field FieldName with aValue
    public void setField(String aFieldName, String aValue);
    // Returns the X3 value of the aFieldName field
    public String getField(String aFieldName);
    // Returns the formatted value of the aFieldName field
    public String getField(String aFieldName, boolean aFormated);
    // Returns the value of the aFieldName field formated with aFormat
    public String getField(String aFieldName, String aFormat);
    // Returns the description of MenuLocal aFieldName field
    public String getMenuLabel(String aFieldName);
    // Returns the field aFieldName at JSON format
    public String getFieldJSON(String aFieldName);
    // Returns the data section in AJSON format
    public String toJSON();
}

For instance

    var wItems=XTD_CTX.getTokenBlock("BlkItems");
   print(wItems.getField("PRIX")+"<br>");    
   print(wItems.getField("PRIX",true)+"<br>");

Call to a web service

The IXtdJsWsvcCall interface is used to call an X3 web service in server scripting.

The web service must be declared as an XTEND interface previously.

The methods of this interface transmit JSON data to X3 web services.

The X3 web services accept two type of XML or JSON data type for the 'data' setup but the JSON format is much easier to control in JavaScript than the XML format because it corresponds to the String representation of JavaScript objects (literal object).

Call interface

public interface IXtdJsWsvcCall
{
    /*------------ Setups ------------*/
    // aInterface   : code of the interface to call
    // aJSONData    : JSON data
    // aFailOnX3Err : True to generate an exception if
    //                an error message is returned by X3
    /*------------ Sub-program ------------*/
    // Returns the standard setups PARCOD/PARVAL to call a sub-program
    public String[][] callSpgGetAXPAR();
    // ------------------------------------------
    // Call to a web service sub-program
    public IXtdAjaxResult callSpgRun(
            String aInterface,
            String aJSONData,
            boolean aFailOnX3Err
        ) throws Exception;
    /*------------ X3 object ------------*/
    // Method Create
    public IXtdAjaxResult callObjCreate(
           String aInterface,
           String aJSONData,
           boolean aFailOnX3Err
        ) throws Exception;
    // ------------------------------------------
    // Method Read
    public IXtdAjaxResult callObjRead(
           String aInterface,
           String aQsKeys,
           boolean aFailOnX3Err
        )throws Exception;
    // ------------------------------------------
    // Methode Update
    public IXtdAjaxResult callObjUpdate(
            String aInterface,
            String aQsKeys,
            String aJSONData,
            boolean aFailOnX3Err
        ) throws Exception;
    // ------------------------------------------
    // Method Delete
    public IXtdAjaxResult callObjDelete(
            String aInterface,
            String aQsKeys,
            boolean aFailOnX3Err
        )throws Exception;
    // ------------------------------------------
    //Other method (aMethod) with a key as setup
    public IXtdAjaxResult callObjActionKey(
            String aInterface,
            String aMethod,
            String aQsKeys,
            boolean aFailOnX3Err
        )throws Exception;
    // ------------------------------------------
    // Other method (aMethod) with XML object data as setup
    public IXtdAjaxResult callObjActionData(
            String aInterface,
            String aMethod,
            String aJSONData,
            boolean aFailOnX3Err
        )throws Exception;
    // ------------------------------------------
    //Left list call
    public IXtdAjaxResult callObjQuery(
            String aInterface,
            String aQsKeys,
            boolean aFailOnX3Err
        )throws Exception;
    /*------------ Trace ------------*/
    // XTEND log file can be accessed via the browser
    // True si trace activée
    public boolean traceOn();
    // ------------------------------------------
    // Start of a log file section
    public void traceBeginStep(String aTrace);
    // ------------------------------------------
    // Trace
    public void traceWrite(String aTrace);
    // ------------------------------------------
    // End of a log file section
    public void traceEndStep();
    /*------------ Divers ------------*/
    // Returns the access url to XTEND web application
    //
http://host:port/xtend - or https://host:portssl/xtend
    public String getWebApplicationUrl(boolean aSecure);
}

Result interface

public interface IXtdAjaxResult
{
    // ------------------------------------------
    //JSON data returned by the web service
    public String getResponseBody();
    // ------------------------------------------
    //JSON data length
    public int getResponseBodyLength();
    // ------------------------------------------
    //True if X3 message
    public boolean hasMessage();
    // ------------------------------------------
    //True if X3 error message
    public boolean hasMsgErr();
    // ------------------------------------------
    //True if X3 warning message
    public boolean hasMsgWarn();
    // ------------------------------------------
    //True if X3 information message
    public boolean hasMsgInfo();
    // ------------------------------------------
    //List of X3 error messages
    public String[] getMsgErrLst();
    // ------------------------------------------
    //List of X3 warning messages
    public String[] getMsgWarnLst();
    // ------------------------------------------
    //List of X3 information messages
    public String[] getMsgInfoLst();
}

Librairie xtdWsvc.js

This library provides utilities to control:

  • web services calls setups
  • JSON result of a call to a web service
  • generated HTML

This library uses the following library: xtdPrototype.js.

Setups and result management

/*------------------ INCLUDE ------------------*/
//Always include the xtdPrototype.js library
#include "xtdPrototype.js"

/*------------------ OBJETS JAVA/JAVASCRIPT -------------------*/
//Returns true if l'objet aObj is a JAVA object
//Returns false if it is a JavaScript object
Object.xtdIsJava(aObj);
//-----------------------------------------------
//Used to convert a Java or JavaScript object in String
Object.xtdToString(aObj);

/*------------------ SETUPS ------------------*/
//Returns setups for the call to a web service
//Classe XTENDWSVC.classParam
//aOptionsJson are JSON options (Classe XTENDWSVC.classJsonOpt)
XTENDWSVC.newParam(aOptionsJson);
//-----------------------------------------------
//Returns setups for the call to a X3 OBJECT web service
//Class XTENDWSVC.classParamObject
//->aTimeStampX3 is a String which contains the TimeStamp of the X3 object
//->aTimeStampX3 ="" if no TimeStamp
XTENDWSVC.newParamXtdObject(aTimeStampX3,aOptionsJson);
//-----------------------------------------------
//Returns setups for the call to a Sub-Program web service
//Class XTENDWSVC.classParamXtdSpg
XTENDWSVC.newParamXtdSpg(aOptionsJson);
//-----------------------------------------------
//Returns setups for the call to a sub-program web service
//'Data access' type Add specific setups
//Class XTENDWSVC.classParamXtdSpgAccess
//->aNbLines is the number of lines to resend
//->aStartAt is the rank of the first line (paging)
XTENDWSVC.newParamXtdSpgAccess(aNbLines,aStartAt,aOptionsJson);

/*------------------ RESULT ------------------*/
//Evaluates the aJSON character string of an X3 web service result
//Returns a JavaScript object
XTENDWSVC.evalResult(aJSON);
//-----------------------------------------------
//Evaluates the result of a sub-program
//Adds specific methods for the result type
//Methods XTENDWSVC.methodsResultSpg
XTENDWSVC.evalResultSpg(aJSON);
//-----------------------------------------------
//Evaluates the result of a sub-program 'Data access'
//Adds specific methods to the result type
//Methods XTENDWSVC.methodsResultSpg
XTENDWSVC.evalResultSpgAccess(aJSON);
//-----------------------------------------------
//Evaluates the result of an Object web service
//Adds specific methods to the result typet
//Methods XTENDWSVC.methodsResultObject
XTENDWSVC.evalResultObject(aJSON);

/*------------------ SETUP CLASSES -------------------*/
XTENDWSVC.classParam=Class.create({
    //Returns JSON options
    options:function();
    //Adds the aCode setups with aValue value
    add:function(aCode,aValue);
});
//-----------------------------------------------
XTENDWSVC.classParamXtdSpg=Class.create(XTENDWSVC.classParam,{
    //Adds a aCode/aValue setup to the AXPAR group
    addAXPAR:function(aCode,aValue);   
});


/*------------------ RESULT OBJECT-------------------*/
//Restult of call to sub-program
methodsResultSpg:{
    //Returns the String value of aCode setup of AXPAR group
    AXPAR:function(aCode);
    //Returns the Integer value of aCode setup of AXPAR group
    //aDefValue is the value if setup non found
    AXPARInt:function(aCode,aDefValue);
}
//-----------------------------------------------
//Result of sub-program call such as 'Data access'
//Methods are used to deal with the paging
methodsResultSpgAccess:{
    //Number of requested records
    askedRecords:function();
    //Number of total records
    totalRecords:function();
    //Number of returned records
    returnedRecords:function();
    //Rang de départ
    startRank:function();
    //True if there are following entries
    hasNext:function();
}
//-----------------------------------------------
//Result of sub-program call such as 'Objet X3'
//The methods used to access information from the last modification
methodsResultObject:{
    //Returns the value of the aField field for the ADXTEC group
    adxADXTEC:function(aField);
    //Renvoie le TimeStamp
    adxTimeStamp:function();
    //Returns the last X3 user code which has modified the object
    adxUser:function();
}

JSON Options

XTENDWSVC.classJsonOpt=Class.create({
    //No publication group in return
    //Each setup is a String grid
    noGroups:function();
    //No lines in the grid with dim>1
    //Each setup is a String grid
    noRows:function();   
    //No labels for local menus
    noLabels:function();
    //Clob fields are not returned
    noClobs:function();
    //Excludes groups contained in aValue
    //aValue is a String or Array of string
    excludeGrp:function(aValue);
    //Includes groups contained in aValue
    includeGrp:function(aValue);
    //Excludes the fields contained in aValue
    //aValue est une String or Array of string
    excludeFld:function(aValue);
    //Includes fields contained in aValue
    includeFld:function(aValue);
});

For instance:

// JSON Options
var wJsonOpt=new XTENDWSVC.classJsonOpt().noRoups().noRows().excludeGrp(["GRP1","GRP2");

// Creation
of sub-program call setup
var wParams=XTENDWSVC.newParamXtdSpg();
wParams.add("AXUSERCODE",wInput.P1);
wParams.add("AXPWD",wInput.P2);
wParams.options().noGroups().includeGrp(["AXLOG_X3"]

Building the HTML

The library includes a XTENDWSVC.classHTMLBuffer class used to build an HTML response to send to the client.

Example of sub-program call

This example is a call to the AXTDLOGIN interface (login sub-program):

  • create setups
  • call the sub-program
  • process the result
      • display errors
      • display an HTML grid with X3 login information returned by the sub-program

GESAY_ADV_SCRIPTING_1.jpg

This is an example, keeping in mind that it is much easier to use tokens in this case.

#include 'libs\xtdWsvc.js'
function callXTDLogin(){
    //User/password setups
    var wInput={P1:'dis001',P2:'adonix'};
    //Log file activated ?
    var wTraceOn=XTD_CTX.traceOn();
    if(wTraceOn){
    //Start of the log file section setups
        XTD_CTX.traceBeginStep("Build WSVC params");
        XTD_CTX.traceWrite("P1="+wInput.P1+ " - P2="+wInput.P2);
    }
    //Creation sub-program object setup
    var wParams=XTENDWSVC.newParamXtdSpg();
    //Valuation of setups
    //AXUSERCODE and APWD are the names of used setup
    //to transmit the user/password
    wParams.add("AXUSERCODE",wInput.P1);
    wParams.add("AXPWD",wInput.P2);
    //Addition of JSON options for the call to sub-program
    wParams.options().noGroups().includeGrp(["AXLOG_X3"]);
    // JSON setups passed on to web service (as for XML setups)
    wParams=Object.toJSON(wParams);
    if(wTraceOn){
        //End of setup log file section
        XTD_CTX.traceWrite(wParams);
        XTD_CTX.traceEndStep();
    }
    //Start of call log file section
    if(wTraceOn)XTD_CTX.traceBeginStep("Call spg");
    //Call to sub-program
    //->false to process X3 errors by program
    var wResult=XTD_CTX.callSpgRun("AXTDLOGIN",wParams,false);
    if (wResult.hasMsgErr()){
        //Process errors
        if(wTraceOn) XTD_CTX.traceWrite("Error message");
        var wLst=$A(wResult.getMsgErrLst());
        print("<span class='intUserMsg'>"+wLst.join('\n')+"</span>");
    }else{
        //Process result
        //Evaluation of JSON data
        var wJSON=XTENDWSVC.evalResultSpg(wResult.getResponseBody());
        //Log file
        if(wTraceOn) XTD_CTX.traceWrite(Object.toJSON(wJSON));
        //Building of a HTML response
        //->Grid of access codes to different X3 folders
        var wHtml=new XTENDWSVC.classHTMLBuffer;
        wHtml.table(["border","0","class","intLine"]);
        wHtml.trFill(["SolutionX3","DossierX3","LangX3","UserX3"],
                     ["class","intRowTitle"]);
        if (wJSON.AX3SOL){
            var wLen=wJSON.AX3SOL.length;
            for(var i=0;i<wLen;i++)
                //Management of styles per alternated lines
                wHtml.trFill([wJSON.AX3SOL[i], wJSON.AX3FLDR[i], wJSON.AX3LANG[i],
                wJSON.AX3USER[i]],["class",i%2==0?"intEvenLine":"intOddLine"]);
                wHtml.endTable();
            }
            print(wHtml.html());
        }
        if(wTraceOn) XTD_CTX.traceEndStep();
    }
}

Call of a script via AJAX

The IXtdAjaxScriptContext interface is available via the XTD_CTX objects for scripts called by AJAX requests.

This interface is used to:

  • call web services (XtdJsWsvcCall interface)
  • access the session context
  • read the content (body) and setups of HTTP request
  • update the ContentType of the result

The print instruction writes the data in a character buffer that will be returned to the client with the ContentType specified by the setHttpContenType method.

// Inherits the call interface of web service IXtdJsWsvcCall
public interface IXtdAjaxScriptContext extends IXtdJsWsvcCall
{
    //Content {{body}} with TEXT format of HTTP request
    public String getHttpBody();
    //Array JSON which contains the setups grid (key/value) of the request
    //Useful if the format is application/x-www-form-urlencoded
    public String getHttpParams();
    //Updates the ContentTYpe of the response
    public void setHttpContenType(String aStr);
    // User login
    public boolean userLogged();
    public String userCode();
    public String userProfile();
    public String userLang();
    // Access session fields
    public Object getSessField(String aFieldName);
    public Object getSessField(String aFieldName, boolean aFormated);
    public void setSessField(String aFieldName, String aValue);
    // Retruns the user data
    public IXtdJsData getUserInfo();
    // Returns user variables
    public IXtdJsData getUserVariables();
    // Returns an action entity
    public IXtdJsActEntity getActionEntity(String aEntityCode, boolean aCreate);
    // Deletes an action entity
    public void removeActionEntity(String aEntityCode);
    // Management of messages for the response
    void addMsgErr(String aMsg);
    void addMsgWarn(String aMsg);
    void addMsgInfo(String aMsg);
}