When calling a RISC-page (e.g. “http://xyz/xyz/abc.risc?ccstyle=defaultrisc”) then internally an HTML page is generated at runtime that contains the corresponding HTML and JavaScript to start the page. Inside this generated HTML page the JavaScript-files (*.js) are listed that are part of the page processing.
By default all JavaScript files are included that form the RISC-client. But you may define own “.js” files on your own and add them to the list. The purpose of own files is to either extend or sometimes override the default JavaScript that comes with the RISC-client.
Any “.js”-file that you add into this directory will automatically be loaded. There is no additional registration required.
You may add own JavaScript files by updating the system.xml configuration file, located in “/webcontent/eclntjsfserver/config/system.xml”.
Example:
<system>
...
...
<riscclientscript src="xxx/yyy/zzzz.js" type="text/javascript" />
<riscclientscript src="aaa/bbb/ccc.js" type="text/javascript"/>
...
...
</system>
The *.js files that you add must reside within the webcontent directory of your project:
<project>
webcontent
aaa
bbb
ccc.js
xxx
yyy
zzzz.js
CaptainCasa uses two the namespaces for all its variables / functions that are defined on window-level (“global level”):
“RISC*” for all RISC related issues – this is the rendering of components
“CC*” for all CaptainCasa related issues – this is the binding level between the rendering and the server side processing
Do not use this namespace on global level!
The JavaScript sources that you add are loaded after the loading of the default RISC JavaScript files. This means: you may override certain behavior of the RISC client.
While JavaScript itself is 100% open and allows you to do “everything” we strongly recommend to only extend the behavior of the RISC client where we explicitly provide possibilities for extension!
(Up to version 20190107 you had to add own, new countries by adding JavaScript code to the client code. From 20190107 on the configuration of client countries and languages is done on server side by adding XML files into the directory webcontent/eclnt/risc/i18n. Please check the Developer's Guide for more details.)
There are predefined exits within the default RISC-client. An exit is an API-call that the RISC-client executes to some outside JavaScript-code. If the outside code exists then it is called, if not then a default behavior is executed.
The file “plugin.js_template” is the one that lists all the exits that are provided by the RISC-client. For implementing the exits on your own you may just copy the “plugin.js_template” file as “/webcontent/eclnt/risc/plugin/plugin.jsp” into you project and then implement these exits that you want to implement. You do not have to implement all exits, so you may comment out or remove the corresponding JavaScript-methods.
The number of exits is quite low at the moment (Sep 2017) – but will be increased step by step.
In case the client runs into some error (e.g. the server is not reachable), it shows some error page:
You may customize this layout by overriding the following method:
/**
* Returns the HTML that is output if an error occurs during communication.
*/
CCPlugin.createClientErrorPageHTML = function(pReloadUrl,pMessage)
{
var sb = new Array();
sb.push("<div style='font-family:Open Sans;width:100%;height:100%;padding:20px;background-color:#FFFFFF;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;overflow:auto'>");
sb.push("<p style='font-family:Open Sans;font-size:25px; font-weight:bold'>Problem</p>");
sb.push("<p style='font-family:Open Sans;font-size:12px'>");
sb.push("A problem occurred when communicating between the client and the server.");
sb.push("</p>");
if (pMessage != null && pMessage != "")
{
sb.push("<hr>");
sb.push("<p style='font-family:Open Sans;font-size:12px'>");
sb.push("Details:");
sb.push("</p>");
sb.push("<p>");
sb.push("<div style='width=100%;background-color:#F0F0F0;padding:10;font-family:Courier New;font-size:11px;border:0px #c0c0c0 solid'>"+pMessage+"</div>");
sb.push("</p>");
}
sb.push("<hr>");
sb.push("<p style='font-family:Open Sans;font-size:12px'>");
sb.push("Typical issues that may have caused the problem are:");
sb.push("<ul>");
sb.push("<li style='font-family:Open Sans;font-size:12px'>The server is not available anymore.</li>");
sb.push("<li style='font-family:Open Sans;font-size:12px'>The session on the server is not available anymore.</li>");
sb.push("<li style='font-family:Open Sans;font-size:12px'>An error occurred in the server side application.</li>");
sb.push("</ul>");
sb.push("</p>");
sb.push("<hr>");
sb.push("<p>");
sb.push("<a href='javascript:RISCConfirmExit.avoidBlocking();location.reload();' style='font-size:12px; font-weight:bold'>Reload current page</a>");
sb.push("</p>");
sb.push("</div>");
return sb.join("\n");
};
Sometimes you want to register own style sheet files in the CaptainCasa page processing. Typical example: you want to add a font to CaptainCasa, that is not loaded by default.
When placing a “.risc”-URL against the CaptainCasa server then a servlet is invoked that generates the HTML page, which then itself starts the JavaScript client as content.
The HTML page looks the following way:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width,height=device-height,user-scalable=no" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="eclnt/risc/fonts/opensans/css/OpenSans.css">
<link rel="stylesheet" href="eclnt/risc/fonts/awesomefont/css/font-awesome.min.css">
<link rel="stylesheet" href="eclnt/risc/fonts/sapicons/css/SAPIcons.css">
<title>CaptainCasa Enterprise Client - RISC-HTML</title>
<link rel="icon" href="eclnt/images/icon.png" />
<!-- ********** STYLES ***************************************************** -->
<link href="eclntjsfserver/styles/defaultlightbluerisc/riscstyle.css" rel="stylesheet"/>
<!-- ********** JAVASCRIPT ************************************************* -->
<script type="text/javascript" src="eclnt/risc/eclntriscbasics.js"></script>
<script type="text/javascript" src="eclntjsfserver/styles/defaultlightbluerisc/riscstyle.js"></script>
<script type="text/javascript" src="eclnt/risc/risc.js"></script>
<script type="text/javascript" src="ztest/zzzzz.js"></script>
<!-- ********** BOOTSTRAP JAVSCRIPT **************************************** -->
<script>
var s_pageBrowser = null;
function initializeApplication()
{
CLog.logINF("initializeApplication() called");
var vUrl = document.URL;
var vIndex1 = vUrl.indexOf("://") + 3;
var vIndex2 = vUrl.indexOf("/",vIndex1);
var vPrefix = vUrl.substring(0,vIndex2);
s_pageBrowser = new CCPageBrowser(vPrefix,"/demos/faces/workplace/workplaceRisc.jsp;jsessionid=950EF8B923889D176CD23847F8D0CDBE?ccstyle=defaultlightbluerisc");
return s_pageBrowser.getUI5Node();
}
</script>
</head>
<body class="riscbody" onload="RISCPage.initialize(1,false);" onbeforeunload="return RISCConfirmExit.confirmExit(event);" onunload="RISCWindowMgr.onunload(event);">
<span><font face="Open Sans" size="100"> </font></span>
<span><b><font face="Open Sans" size="100" > </font></b></span>
</body>
</html>
You see, that in the “<head>...</head>” section style sheets are contained – e.g. there are three fonts definitions that are contained, including the OpenSans-font (this is the font addressed by CaptainCasa default style) and including the “awesomefont”-font and the “SAP-icon”-font.
In the configuration file “eclntjsfserver/config/system.xml” there is a section which allows to directly define the CSS-filese to be included:
<system>
...
<!--
*************************************************************************
Configuration of additional styles includes in RISC client
*************************************************************************
-->
<riscclientstyle src="xxx/yyy/zzzz.css"/>
<riscclientstyle src="aaa/bbb/ccc.css"/>
...
</system>
The files need to be part of your web content directory.
Each style is represented by one directory within “<webcontent>/eclntjsfserver/styles”. Any css-file that is placed here is automatically available on client side.
Please note: only the CSS files of the current style are loaded! If e.g. style “xxx” extends style “yyy” then only the directory for style “xxx” is scanned. There is no cascading scanning.
A typical CaptainCasa project is separated into three webcontent-directories.
webcontent – this is the directory that contains your artifacts
webcontentbuild – this is the directory that contains all compiled files
webcontentcc – this is the directory contains all CaptainCasa addons to you web application
All three directories are copied and merged at runtime (e.g. they are copied into one tomcat/webapps/<app> directory).
The adequate directory for adding your artifacts always is the “webcontent” directory! So, if e.g. using the default style “defaultlightbluerisc” of CaptainCasa, do NOT add your own .css-files to the webcontentcc-directory (where the original CaptainCasa style is kept), but add your own .css-files to:
<project>
webcontent
eclntjsfserver
styles
defaultlightbluerisc
own1.css
own2.css
webcontentbuild
webcontentcc
Fonts are added by corresponding CSS-files in which the font and its location is defined.
Example: the default font that is used is defined by the following CSS:
/* open-sans-regular - latin */
@font-face {
font-family: 'Open Sans';
font-style: normal;
src: url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-regular.eot'); /* IE9 Compat Modes */
src: local('Open Sans'), local('OpenSans'),
url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-regular.woff') format('woff'), /* Modern Browsers */
url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-regular.svg#OpenSans') format('svg'); /* Legacy iOS */
}
/* open-sans-600 - latin */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: bold;
src: url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-600.eot'); /* IE9 Compat Modes */
src: local('Open Sans Semibold'), local('OpenSans-Semibold'),
url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-600.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-600.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-600.woff') format('woff'), /* Modern Browsers */
url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-600.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/open-sans-v15-cyrillic_latin_latin-ext_greek_cyrillic-ext_greek-ext-600.svg#OpenSans') format('svg'); /* Legacy iOS */
}
This CSS-file is placed into the web-content, same with all the files which are referenced inside the file. The location of files inside the web-content are up to you.
Inside the client certain calculations are done on base of standard functions that access the font metrics. These standard functions sometimes do not calculate correctly when calling them within the first CaptainCasa dialog. Example: the text in buttons is not correctly sized, so that is is cut.
For this reason it is important to access the font as early as possible, so that the browser already internally registers the font metrics – and so that first calls from CaptainCasa into the font metrics functions are correctly calculated.
You do this by registering the font in the /eclntjsfserver/config/system.xml file:
<system ...>
...
<riscclientfontaccess face="...nameOfFont..."/>
...
</system>
As consequence the font is already accessed in the page that is output as first (blank page with waiting-icon).
Take a look onto the following page:
There is some outside HTML page, that internally embeds a CaptainCasa page. And there is the possibility to interact in both directions.
The outside page is not loaded from the same domain as the inside page.
In principal pages between different domains can only talk to one another by using message-events. There is no possibility to directly call JavaScript functions due to security restrictions (cross site scripting).
Inside CaptainCasa dialogs there is a so called “Message Bus”. This message bus is a central instance within the client to which you can send messages, and from which you can receive messages.
Each message is a string in the format “<messageName>(<param>,<param>,...)”
Listening and receiving is done by using an invisible component MESSAGELISTENER. In this component you register for the message names that you are interested in. Once a message is received then a corresponding ACTIONLISTENER is called no server side. The message is part of the event data.
Vice versa a CaptainCasa dialog can send messaged by using Java-API “AsynchMessageBus”. Messages are normally only processed within the CaptainCasa dialog, but you can use API “AsynchMessageBus.addMessage(String message, boolean withParentDelegation)” and can define that messages are also delegated as browser-message-event to the parent of the current dialog.
This is the HTML of the outside page:
<html>
<script>
function sendMessage()
{
var f = frames.IFRAME1;
var t = document.getElementById("SEND").value;
var m = "messagebus:todemoembedded("+t+")";
f.postMessage(m,"*");
}
function _receiveMessageEvent(e)
{
if (e == null) e = window.event;
var s = e.data;
if (s != null && s.indexOf("messagebus:tooutsidepage(") == 0)
{
s = s.substring(11);
document.getElementById("RECEIVED").value = s;
}
}
window.addEventListener("message",function(e) {_receiveMessageEvent(e);});
</script>
<h2>This is the outside HTML page</h2>
<input id="SEND" value="Harry" style="width:600px" >
<br>
<a href="javascript:sendMessage();">Send message</a>
<br>
<br>
<br>
<input id="RECEIVED" value="(Nothing received yet.)" style="width:600px" disabled="true">
<br>
<h2>This is the contained CC page</h2>
</html><iframe id="IFRAME1" name="IFRAME1" src="http://localhost:8080/demos/workplace.demoembeddeddialog.risc" width="600" height="400"></iframe>
<br>
You see:
The CaptainCasa page is included as IFRAME.
Messages are sent through the sendMessage()-function – creating a message with the name “messagebus:” and then the text of the message. In this case the message name is “todemoembedded”.
The page registers for messages (window.addEventListener) and receives the message in a corresponding function (_receiveMessageEvent).
The inner page is a quite simple one:
<t:beanprocessing id="g_1">
<t:messagelistener id="g_2"
actionListener="#{d.DemoEmbeddedDialog.onMessageReceived}"
commandfilter="todemoembedded" />
</t:beanprocessing>
<t:rowtitlebar id="g_3" text="Embedded dialog" />
<t:rowheader id="g_4" />
<t:rowbodypane id="g_5" rowdistance="10">
<t:row id="g_6">
<t:label id="g_7" font="size:15"
text="Outside page ==> CaptainCasa" />
</t:row>
<t:row id="g_8">
<t:textarea id="g_9" height="100%"
text="#{d.DemoEmbeddedDialog.messageReceived}" width="100%" />
</t:row>
<t:rowline id="g_10" />
<t:row id="g_11">
<t:label id="g_12" font="size:15"
text="CaptainCasa ==> Outside page" />
</t:row>
<t:row id="g_13">
<t:textarea id="g_14" height="100%"
text="#{d.DemoEmbeddedDialog.messageToSend}" width="100%" />
</t:row>
<t:row id="g_15">
<t:button id="g_16"
actionListener="#{d.DemoEmbeddedDialog.onSendButtonAction}"
text="Send to outside page" width="100+" />
</t:row>
</t:rowbodypane>
<t:rowstatusbar id="g_17" />
The Java code is:
public class DemoEmbeddedDialog
extends PageBean
implements Serializable
{
// ------------------------------------------------------------------------
// members
// ------------------------------------------------------------------------
String m_messageReceived = "(Nothing received yet.)";
String m_messageToSend = "Some message to the client.";
// ------------------------------------------------------------------------
// constructors & initialization
// ------------------------------------------------------------------------
public String getPageName() { return "/workplace/demoembeddeddialog.jsp"; }
public String getRootExpressionUsedInPage() { return "#{d.DemoEmbeddedDialog}"; }
// ------------------------------------------------------------------------
// public usage
// ------------------------------------------------------------------------
public String getMessageToSend() { return m_messageToSend; }
public void setMessageToSend(String value) { this.m_messageToSend = value; }
public String getMessageReceived() { return m_messageReceived; }
public void setMessageReceived(String value) { this.m_messageReceived = value; }
public void onSendButtonAction(javax.faces.event.ActionEvent event)
{
AsynchMessageBus.addMessage("tooutsidepage("+m_messageToSend+")",true);
}
public void onMessageReceived(javax.faces.event.ActionEvent event)
{
if (event instanceof BaseActionEventMessage)
{
BaseActionEventMessage e = (BaseActionEventMessage)event;
StringBuffer sb = new StringBuffer();
sb.append("Command: " + e.getMessageCommand() + "\n");
String[] params = e.getMessageParameters();
for (String param: params)
{
sb.append("Parameter:" + param + "\n");
}
m_messageReceived = sb.toString();
}
}
}
You see:
In the page there is a MESSAGELISTENER component listening to message name “todemoembedded”. It is bound to metho “onMessageReceived”.
In the code there is a calling of “AsynchMessageBus.addMessage(...)” if the “Send to outside page” button is pressed by the user.
The protocol into both directions is completely up to you. The basic structure is:
nameOfMessage(param1,param2,param3,...)
Do not use “strange characters” within the message parameters. If you want to transfer e.g. complex XML data or JSON strings, then e.g. use Base64 encoding to transfer all content into simple characters before passing it as parameter of the message.
First of all: CKEditor is a 3rd party product – please carefully read the corresponding license and usage terms from https://ckeditor.com!
The integration is done using the SIMPLEHTHMLEDITOR component. This component internally opens up an IFRAME in which CKEditor is started. The communication is done through a bridging page which receives JavaScript messages from the component and transfers them into corresponding JavaScript calls for CKEditor.
CaptainCasa comes with the following default scenario: the CKEditor is loaded from the following directory:
<project>/webcontentcc/eclnt/risc/ext_ckeditor/v492
“v492” is the version of CKEditor – which may be different from release to release. CaptainCasa by default only provides the “Basic Package” of CKEditor, there are multiple more packages available – with a different and a configure-able set of features.
You may download these packages from the CKEditor web site. The current download address for CKEditor is “https://ckeditor.com/ckeditor-4/download/”.
There is one additional file in this directory – the bridging page between the CaptainCasa processing and the CKEditor processing. The name of this file is:
ext_ckeditor.html
In the SIMPLEHTMLEDITOR component you can explicitly specify the bridging page by suing attribute BRDIGEPAGE, the default currently is “eclnt/risc/ext_ckeditor/v492/ext_ckeditor.html”.
The best way to install own versions of CKEditor is:
Download the corresponding version from CKEditor
Place the version in your webcontent – we recommend to use a similar directory location as CaptainCasa does.
Copy the bridging page “ext_ckeditor.html” from the CaptainCasa default directory (webcontentcc) directory into the directory:
Example:
<project>
webcontent
eclnt
ext_ckeditor
v492_OwnVersion
…
… <== all CKEditor files
…
ext_ckeditor.html
webcontentbuild
webcontentcc
(If using Maven-style projects than the directory structure looks different. The “webcontent” directory then is “source/main/webapp”.)
In the dialog definition (.jsp) in which you use the SIMPLEHTHMLEDITOR component assign the value “eclnt/ext_ckeditor/v492_OwnVersion/ext_ckeditor.html” to the attirbute BRIDGEPAGE.
Do not start the attribute value of BRIDGEPAGE with a leading “/”!
Do not copy your version of CKEditor into the “webcontentcc”-directory! This directory is owned and managed by CaptainCasa.
CaptainCasa provides a pre-configured bridge to embed Chart.js diagrams. By using the component CHARTJS you can easily transfer configuration data and chart data into a sub-page (called bridge-page). Chart.js is executed in an HTML-IFRAME – and as consequence runs completely isolated from the normal CaptainCasa client processing.
Chart.js and the bridge page are delivered in the following directory of eclntjsfserver_<version>.jar:
eclnt
risc
ext_chartjs
Up to 20231120 the content of the directory was:
It contained the required libraries and some brdige-html pages. The bridge-page that are the ones with stable names throughout releases are:
ext_chartjs.html => normal bridge page
ext_chartjs_datalabels.html => in addition using datalabels add ons
Since 20231120 we internally use npm (node package manager) for creating the bridge pages. So the directory content now looks like:
The advantage: npm makes sure that the up to date libraries together with up to date dependencies are used. The disadavantage: you need to know the setup of npm projects in order to do some own or modified implementation of the bridge page.
CaptainCasa provides its npm projects as part of the CaptainCasa GIT repository. Here they are embedded into the “eclnt_clientrisc” project.
Within each of the “npm_*” directories there is a short explanation how to easily run the npm build management.
Let's assume you come from some older CaptainCasa version e.g. 2023113 (the last one before changing to Chart.js 4.2.0 and before changing to npm) and you want to continue to use the older version (with Chart.js 2.9 and without npm).
In this case perform the following steps:
Extract the eclntjsfserver_<version>.jar file into any directory.
Copy the content of “eclnt/risc/ext_chartjs” into either a resource directory (Maven: src/main/resrouces/<yourDirectory>) or into the web content directory (Maven: src/main/webapp/<yourDirectory>). - CaptainCasa accesses web resources both through the class loader (=> resource directory) or through the web content (=> web content directory), so it's up to you where to place the files.
In the definition of the CHARTJS component defined the bridge page that is now the old one. Example:
...
<t:chartjs ... bridgepage=”/<yourDirectory>/ext_chartjs.html”
...
CaptainCasa knows two session tracking modes:
“URL” (URL encoding)
“COOKIE” (Cookie usage)
The default is “URL” - but you may change to “COOKIE” easily. Please read the chapter “Http Session Managament” within the Develoer's Guide for more information.
SSO frameworks typically transfer information based on cookies, or they store information based on the JSESSIONID-cookie-value. So in genreal use “COOKIE” based session tracking within CaptainCasa.
There is quite some variance of frameworks in the SSO area. Typically the user is routed to some login page of the SSO framework automatically when first time accessing the application. After successful logon the browser is routed back to the application page that was requested.
After logon SSO information typically is available by accessing information that is part of the http-request of the http-session. Use the CaptainCasa facade “HttpSessionAccess” in order to access these objects:
HttpSessionAccess.getCurrentRequest()
HttpSessionAccess.getCurrentHttpSession();
Example: from the request you may access the user-principal information, that is some standarf for storing login information.
Please note: you need to reference the servlet-API library within the classpath of your project for accessing the http-objects. For Maven-style projects it is already integrated, for default projects you may embed the tomcat/libs/servlet-api.jar.
In single sign on (SSO) scenarios you may call a CaptainCasa page e.g. from some starter page – and you may pass an authorization token (e.g. Bearer-token) to be used with every http request that is called from the CaptainCasa dialog.
You do so by setting a cookie “CCHeaderField_Authorization” and passing the full authoritation info (type + token).
Example: you may define an “index.html” within your webcontent:
<html>
<script src="keycloak/keycloak.js"></script>
<script>
var keycloak = new Keycloak('keycloak/keycloak.json');
keycloak.init
(
{
onLoad: 'login-required'
}
).success
(
function(authenticated)
{
keycloak.loadUserProfile().success
(
function(profile)
{
CCDataTransfer_BearerToken = keycloak.token;
document.cookie =
"CCHeaderField_Authorization=Bearer"+keycloak.token;
startPage();
}
);
}
);
function startPage()
{
document.location.href = "test.risc?ccstyle=defaultlightbluerisc";
}
</script>
<body>
</body>
</html>
On the receiving side you may then access the http header parameter in the following way:
package managedbeans;
import java.io.Serializable;
import javax.servlet.http.HttpServletRequest;
import org.eclnt.editor.annotations.CCGenClass;
import org.eclnt.jsfserver.defaultscreens.Statusbar;
import org.eclnt.jsfserver.pagebean.PageBean;
import org.eclnt.jsfserver.util.HttpSessionAccess;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
@CCGenClass (expressionBase="#{d.TestUI}")
public class TestUI
extends PageBean
implements Serializable
{
String m_info = "";
public TestUI()
{
collectAuthInfo();
}
public String getPageName() { return "/test.jsp"; }
public String getRootExpressionUsedInPage() { return "#{d.TestUI}"; }
private void collectAuthInfo()
{
m_info = "";
HttpServletRequest req = HttpSessionAccess.getCurrentRequest();
String authorization = req.getHeader("Authorization");
m_info += "AUTHORIZATION:\n" + authorization + "\n\n";
if (authorization != null && authorization.startsWith("Bearer"))
{
String token = authorization.substring("Bearer".length());
m_info += "BEARER TOKEN:\n" + token + "\n\n";
}
}
public String getInfo() { return m_info; }
}
In the example some bearer-token is passed from the client to the server. You may now use some JWT decoder to interpret the data contained in the token.
The CaptainCasa server environment comes with a special feature that is inevitably important for solving complex bugs within the CaptainCasa frontend processing – that (as usual...) only happen inside your own environment and cannot be reproduced at CaptainCasa side.
There is a certain recording of all http traffic that is exchanged between the browser and the server. The recorded files can then be sent to CaptainCasa so that CaptainCasa can replay the frontend – the requests are responded from the files that you recorder. The result: CaptainCasa can exactly replay your scenario.
The recorded information contains all the traffic between your browser and your server. If the content contains critical information (including passwords, business information, …) then this is logged as consequence – and readable as clear text. So only use the recording feature in demo systems with demo user accounts...! If in doubt about security, please contact CaptainCasa.
In order to avoid a mis-usage of the http traffic recording CaptainCasa restricted this feature to be only use-able in scenarios, in which the browser accesses the server by a URL starting with “http://localhost...” or “https://localhost...”.
Recording of http traffic is switched off by default. There are two ways to switch on:
Via configuration in “eclntjsfserver/config/system.xml”
<system>
...
...
<responselogger active="true"/>
...
...
</system>
Via system property that you pass when starting you server by using “-D” parameters that are added to the call of the Java runtime.
Tomcat:
...
...
set JAVA_OPTS= ... -Dcc.responseLoggerActive=true ...
...
...
catalina ... run
Please also pay attention: the configuration MUST NOT be active in production scenarios! It is only to be used in development scenarios. (Otherwise any traffic might be recorded!)
We explain the sequence of steps by using as example our demo workplace, which is available as “http://localhost:8080/demos/workplace.workplaceRisc.risc?ccstyle=defaultrisc” after installation. - Please note: when recording your application you need to exchange the “demos” of the URL to the name of your application for all the steps that are explained in the following text!
To do so you just need to call URL “http://localhost:8080/demos/switchrecordon”. Remember: you need to exchange the name “demos” with the name of your application!
The text within the screen tells you the directory, in which the recorded files are placed.
Now: clear your browser cache!
This is 100% important and the most common problem when recording. If the browser cache is not cleared then certain resources are not requested through the network and are not recorded on server side as consequence.
You have to clear the browser cache every time when recoding a sequence!
Unfortunately clearing the cache is much different from browser to browser.
In Chrome:
In Firefox:
Now you may start (e.g. in a second tab) the URL of your application just as normal. In the background on server side each request/response is recorded.
Per request/response two files are written:
The content of the response (“.content”)
Parameters of the response (“.params”)
Call URL “http://localhost:8080/demos/switchrecordoff” - and again replace “demos” by the name of your application:
Now you may zip all of the recorded files to one file – and send it to CaptainCasa – together with the start-URL that you used.
Well, replaying typically is done on CaptainCasa side, but you may want to do it for any reason on your own.
Just call URL “http://localhost:8080/demos/switchreplayon” and now the server will not work normally anymore but will fulfill all request by finding responses in the recorded files.
When calling your application URL “http://localhost:8080/demos/workplace.workplaceRisc.risc?ccstyle=defaultrisc” then all responses are coming “immediately” from the file system.
Finally switch the replay mode off by calling “http://localhost:8080/demos/switchreplayoff”.
There's a high level of compatibility between Swing/FX client and RISC client. Nevertheless there are some issues to take care of.
When coming from the JavaFX/Swing environment then please download the most up to date version from http://www.CaptainCasa.com/java. This is the “big” download, in which also the Swing and FX-client is included. The “normal” download only includes the RISC-HTML client anymore.
Just normally upgrade your project. This is typically done by opening the project within the CaptainCasa toolset. A dialog will appear in which you are informed that your project needs some update – and a corresponding button needs to be pressed.
There are a couple of new items in the web.xml that need to be added. Copy all the CaptainCasa items from web.xml_template into your web.xml.
Use the “Reload” within the toolset to redeploy your application.
Start your outest page (starting page) within the browser in the following way:
http://<host>:<port>/<webapp>/[<dir>.]<page>.risc?ccstyle=defaultrisc
Example: you run the application on the default Tomcat, your application has the name “testapp”. Inside your application there is an “outest.jsp”, directly located in the webcontent-directory. In this case the URL is:
http://localhost:50000/testapp/outest.risc?ccstyle=defaultrisc
Example: the same situation but now the outest page is located in the “webcontent/pages”-directory:
http://localhost:50000/testapp/pages.outest.risc?ccstyle=defaultrisc
The BGPAINT attribute is not supported with all the options that were available in the Swing/FX environment. There is a certain compatibility level – but the best idea is to switch to these BGPAINT-commands that are available for all platforms (error, mandatory – and all the commands starting with “bg”, e.g. “bgimage”).
In Swing/FX the file name always was transferred with its full absolute path (e.g. “c:/xyz/xyz/abc.txt”). In RISC the client only transfers the file name – due to security reasons (e.g. “abc.txt”).
When having used CaptainCasa Enterprise Client with its Swing or with its JavaFX client then your project contains some files which are obsolete when “only” using the RISC client anymore.
These files may be removed from the project in order to decrease its size and in order to tidy up. When using the default project layout then these files are part of the “webcontentcc” directory – so they are part of the content, that is added by CaptainCasa into your project.
webcontentcc
eclnt
lib <== remove
libfx <== remove
ui5 <== remove
eclntjsfserver
ht <== remove
htstyle <== remove
javainstall <== remove
styles
default <== remove
defaultfx <== remove
ccdark <== remove
cceditor <== remove
cceditorlight <== remove
cceditorlightfx <== remove
ccmetrofx <== remove
cctouch <== remove
cctouchlight <== remove
WEB-INF
lib
jnlp-servlet.jar <== remove
The best was to clean up your CaptainCasa installation is:
Remove the existing installation
You may “remove” your existing installation by just renaming the directory of the installation – in this case you still have your old installation pre-served.
Install CaptainCasa-RISC in the directory, in which your installation was done
There is only one type of content which you need to preserve, i.e. which you have to save before removing and which you have to bring in again after installation: the project definitions of the CaptainCasa toolset.
So please save all files in...
<installdir>
server
tomcattools
webapps
editor
config
projects
*.xml <== to be saved
...before removing the installation. And reapply the files at the same location after having installed CaptainCasa-RISC.
Part of the CaptainCasa installation is a Tomcat that is used for deploying your projects.
<installdir>
server
tomcat
This tomcat is “empty” if having removed the existing installation and having re-installed. In order to deploy your projects you need to open the project within the CaptainCasa toolset and you need to execute the “Reload Server” function.
The server side of creating a new component is covered in the Developers Guide. Please check the following chapter “Adding own Components”.
You need to:
Create a tag library file (.tld)
Register components in faces-config.xml
Set up a configuration file contollibraries.xml
Write a component tag and a component class
Register the component so that is is usable in the CaptainCasa toolset (controlarrangement.xml, ...)
The result: the component with its attributes is part of the XML layout that is sent from the server to the client.
The “client side” means adding some JavaScript functions/classes that render the components at the right place in the right way. The JavaScript functions are added by registering corresponding .js-files in system.xml. The .js files either are located in the web content or in the source area – just like normal web resources.
On client side there are two JavaScript classes (at runtime object) that you have to develop:
The “element” class
The “control” class
The “element” class is a direct reflection of the XML element that is sent to the client side. It allows to access the XML attributes and to find out which attributes have changed when a response from the server side is processed. An element object is created when the corresponding XML element is first time processed – and is removed if the XML element disappears from the layout definition's XML. Typically the “element” class (at runtime: object) is responsible for creating and registering a “control” object which then is part of the dialog. It transfers the XML attributes into the corresponding settings of the control.
The “control” class is in principle an independent class that defines a certain control. Example: there is a “RISCButton”-class to provide a button control. This class (if perfectly programmed!) does not know anything about the “element” class(es), so it should be as independent as possible to be flexibly usable.
In reality there is often some direct relation between the element class and the control class, but in principal you should pay attention to the split up between the “control” (rendering, direct event processing) and the “element” (layout transfer, connection to server side).
Example:
A button-”control” could directly invoke a roundtrip to the server side, when being pressed.
...but: this would mean that the button knows about the server-communication-framework – which is not the button's purpose!
...better way: the button-”control” fires some action-event when being pressed, the “button”-element catches this event and decides to initiate the roundtrip. - As result: the button is usable in any usage scenario.
For (nearly) each CaptainCasa component there is a corresponding Element-class. (We say “nearly” because sometimes one class is used by several components.)
The naming convention is: “eclnt_controls_ac/cc_<nameOfControlInUpperCase>.js”. Example: “eclnt_controls_ac_FIELD.js”, “eclnt_controls_cc_ICON.js”.
For each end-control there are some important methods:
“init_CC<Control>Element” - this is the pseudo-constructor. It is called at the very end of each class definition.
In the constructor you create the real “control”-object and store it in the object by calling “bindUI5Object(...)”.
“applyComponentData_CC<Control>Element” - this is the method which is called every time the attributes of the element are changed within the response processing. You can find out which properties were changed and can take over the changed values into the actual control.
For elements which may have sub-elements (e.g. a PANE element may have ROW elements) there are two more methods:
“removeChildNode()”
“addChildNode()”
Check in the existing classes the way, in which inheritance is managed. Each implemetation of a method (e.g.for applyComponentData) first calls its super-method before starting its own activities.
The naming conventions for the file names which are used in CaptainCasa is “eclntrisccomponets_<ControlName>.js”.
Example: the button component is defined in file “eclntrisccomponents_button.js”, the class name (function name) of the button is “RISCButton”.
The central class which is the parent of all components is the class “RISCComponent” (defined in “eclntrisccomponents.js”). This class includes a lot of standard functions, such as:
Managing child components (addChild(), removeChild(), ...)
Managing sizing (getMinimumSize(...), getPreferredSize(...))
Managing colors, fonts, background styling, style class assignments
A typical component (e.g. RISCButton) derives from “RISCComponent” and first needs to override/implement certain methods:
“calculateMinimumSize” - define the minimum width/height of the content occupied by this method.
“layoutChildren” - layout the child components (e.g. a button needs to position its contained text component)
A component can register to various basic events (set<EventCategory>Listener, e.g. “setClickListener”) and then process these event in its “reactOnRISCEvent” method.
Again you need to pay attention to inheritance aspects, and properly isolate and call the parent functions from your implementation.
This chapter only can give rough overview information. We ask you to really get into the code (which is super-necessary with JavaScript anyway...) and follow some example components – to find out, that things are quite simple indeed and well-structured.
There's an API documentation available at: