This document

Concepts

Different levels of individualization

Applications consist out of parts, that are “always the same” throughout different types of applications. Example:

And applications consist out of parts that are individual for a specific application.

Some of these specific parts are add-ons to the standard parts:

Other parts are completely decoupled from standards - and are individually designed. Example:

What you normally would do...

Assuming you have all resources available you typically would follow a strategy like this one:

The framework should allow to be extended to a certain level - in order to bring in own processing or visualization rules.

For the decoupled, individual parts of the application you would not try to abuse the standard parts so that you force everything into it! You would allow to just “develop” - based on a solid, efficient environment.

The borders between what is standard level, what is extension level and what is individual level are not define-able in a fix way. So you would never follow a strategy to implement these levels in different technologies. - But you would prefer to have a consistent technology and architecture that is used for all of these levels - so that knowledge can be shared across the levels and so that deployment and runtime behavior remains consistent.

...and what CaptainCasa RapidApp is doing!

Well, this is exactly what CaptainCasa RapidApp is doing! Defining one consistent implementation infrastructure based on

“No-code” for the standard parts!

There are a couple of default issues coming with any application project that you just can set up by definition, without any coding. What you get is:

“Low-code”-Java for enriching the default!

The default lets you define simple and complex entities which already cover many types of integrity rules for processing and validating entity objects. But you may add:

All this can be done by predefined, easy to follow extensions for enriching the default. The base classes to apply the extensions to are already created by the default processing - so you have clear entry points to add additional logic.

Extensions are created using “guided Java” as language. This includes:

“Any”-Java for free-style development!

The “No-code” and “Low-code” parts address these issues which are “common standard”: User-management, workplace management, entity management, sophisticated form management on persistent data.

What's about the issues which are not standardized?

Examples:

Here you use “normal Java” together with the normal CaptainCasa Enterprise Client which directly binds user interface processing to Java without any client-side development.

Advantages

Structural/ architectural advantages

You application follows one architectural structure:

Project advantages

You project will jump-start because the skeleton of the application is visible immediately: the workplace, the entities, the forms to edit these entities.

Your project team does not have to burn development resources for “stupid issues” - e.g. lists of data, selection of an data item, open up detail dialog to edit and save the data... These issues come out of the box and can be customized without Java coding.

Your project team can directly focus on these things which matter: the individual issues, that make your application and that add value to your application.

Inside your project team you can split up resources according to the different individualization levels:

 

Installation

Two installation steps

Starting the server and the tools

Creating your first RapidApp project

Video tutorials

Create project

Create & configure the database

db_url=jdbc:hsqldb:file:./data/...nameOfProject...

db_driver=org.hsqldb.jdbc.JDBCDriver

db_username=SA

db_password=

db_sqldialect=hsqldb

db_autotrim=true

db_withpooling=true

db_url=jdbc:postgresql://localhost:<yourPort>/<yourDB>

db_driver=org.postgresql.Driver

db_username=yourPostgresUser

db_password=yourPostgresPassword

db_sqldialect=postgres
db_autotrim=true

db_withpooling=true

Define your first content

Define the first entity “article”

<property id="id" text="Id" dataType="ccda_base.idString50" key="true"/>

<property id="description" text="Description" dataType="ccda_base.textLong500"/>

<property id="name" text="Name" dataType="ccda_base.textShort100" mandatory="true"/>

Generate and deploy

Build your list UI

<...installDir...>/server/tomcat/webapps/<...yourApplication...>

Build your detail UI

Test the whole scenario

Setting up “link” relations

Meta data

<entity id="unitOfMeasure" isPublic="true" text="Unit of measure">

    <property dataType="idUnitOfMeasure" id="id" key="true" mandatory="false" text="Id"/>

    <property dataType="ccda_base.textShort100" id="name" mandatory="true" text="Name"/>

</entity>

<reference id="refUnitOfMeasure" isPublic="true" refEntity="unitOfMeasure" refIdColumn="id" refTextColumn="name" text="Ref to unit of measure"/>

<entity id="article" isPublic="true" text="Article">

    <property dataType="idUnitOfMeasure" id="unitOfMeasureId" mandatory="false" propertyReferenceId="refUnitOfMeasure" text="Base unit of measure" validateByValidValues="true"/>

</entity>

UI processing

Setting up “embedded” relations

order:        orderId              || ... | ... | ...

order item:   orderId | itemNumber || ... | ...

person:      personId || ... | ...| ...| addressId | ...

address:     addressId || ... | ... | ...

Meta Data

UI layer

Basic meta data definitions

Entity

Data type

Reference

Authorization

package org.eclnt.dataapp.logic.authority;

 

import org.eclnt.dataapp.logic.authorization.*;

 

public class ARCCEntityRights

    extends AuthorizationRequest

{

    public static final String TYPE_ID = "eclnt_dataapp.CCEntityRights";

    public static final String ASPECT_entity = "entity";

    public static final String ASPECT_action = "action";

 

 

    public ARCCEntityRights()

    {

        super(TYPE_ID);

    }

    

    public ARCCEntityRights setEntity(Object value) { addAspectValue(ASPECT_entity,value); return this; }

    public ARCCEntityRights setAction(Object value) { addAspectValue(ASPECT_action,value); return this; }

 

}

ARCCEntityRights r = new ARCCEntityRights()

    .setAction(ENUMEditMode.EDIT)

    .setEntity(BCIRuntime.instance().getEntityIdByClass(selectedObject.getClass()));

boolean authorized = AuthorizationManager.instance().checkIfUserIsAuthorized(r);

Public page beans

Applying own logic

Importing the project

Generation of artifacts

Why at all?

Separation between generated code and own code

Adding own validation logic

Adding own view elements / logic

Data object and Data context

Setting up the user workplace

Basics

Opening the workplace

Defining the function tree

Functions trees

Design time functions trees

Storing of design time functions trees

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workplaceFunctionTreeInfoNode>
   <folderOpened>false</folderOpened>
   <subNodes>
       <text>My application</text>
       <folderOpened>true</folderOpened>
       <subNodes>
           <text>Flexible analysis</text>
           <folderOpened>true</folderOpened>
           <subNodes>
               <text>Prompting</text>
               <folderOpened>false</folderOpened>
               <workpageStartInfo>
                   <pageBeanName>org.eclnt.ccda_base.view.CCAppPrompting</pageBeanName>
                   <id>org.eclnt.ccda_base.view.CCAppPrompting</id>
                   <openMultipleInstances>true</openMultipleInstances>
                   <decorated>true</decorated>
                   <popupSupported>false</popupSupported>
                   <closeSupported>true</closeSupported>
                   <openAsPopupByDefault>false</openAsPopupByDefault>
                   <excludeFromSavePerspective>false</excludeFromSavePerspective>
                   <paramMap/>
                   <sortIndex>-1</sortIndex>
               </workpageStartInfo>
           </subNodes>
       </subNodes>
       <subNodes>
           <text>Order Management</text>
           <folderOpened>true</folderOpened>
           <subNodes>
               <text>#{rr.tuto1['VIEW.test.tuto1.view.dialogs.OrderList']}</text>
               <folderOpened>false</folderOpened>
               <workpageStartInfo>
                   <pageBeanName>OrderList</pageBeanName>
                   <id>OrderList</id>
                   <openMultipleInstances>false</openMultipleInstances>
                   <decorated>true</decorated>
                   <popupSupported>false</popupSupported>
                   <closeSupported>true</closeSupported>
                   <openAsPopupByDefault>false</openAsPopupByDefault>
                   <excludeFromSavePerspective>false</excludeFromSavePerspective>
                   <paramMap/>
                   <sortIndex>-1</sortIndex>
               </workpageStartInfo>
           </subNodes>
       </subNodes>
       <subNodes>
           <text>Master data</text>
           <folderOpened>true</folderOpened>
           <subNodes>
               <text>#{rr.tuto1['VIEW.test.tuto1.view.dialogs.ArticleList']}</text>
               <folderOpened>false</folderOpened>
               <workpageStartInfo>
                   <pageBeanName>ArticleList</pageBeanName>
                   <id>ArticleList</id>
                   <openMultipleInstances>false</openMultipleInstances>
                   <decorated>true</decorated>
                   <popupSupported>false</popupSupported>
                   <closeSupported>true</closeSupported>
                   <openAsPopupByDefault>false</openAsPopupByDefault>
                   <excludeFromSavePerspective>false</excludeFromSavePerspective>
                   <paramMap/>
                   <sortIndex>-1</sortIndex>
               </workpageStartInfo>
           </subNodes>
           <subNodes>
               <text>#{rr.tuto1['VIEW.test.tuto1.view.dialogs.PriceListList']}</text>
               <folderOpened>false</folderOpened>
               <workpageStartInfo>
                   <pageBeanName>PriceListList</pageBeanName>
                   <id>PriceListList</id>
                   <openMultipleInstances>false</openMultipleInstances>
                   <decorated>true</decorated>
                   <popupSupported>false</popupSupported>
                   <closeSupported>true</closeSupported>
                   <openAsPopupByDefault>false</openAsPopupByDefault>
                   <excludeFromSavePerspective>false</excludeFromSavePerspective>
                   <paramMap/>
                   <sortIndex>-1</sortIndex>
               </workpageStartInfo>
           </subNodes>
           <subNodes>
               <text>#{rr.tuto1['VIEW.test.tuto1.view.dialogs.CustomerList']}</text>
               <folderOpened>false</folderOpened>
               <workpageStartInfo>
                   <pageBeanName>CustomerList</pageBeanName>
                   <id>CustomerList</id>
                   <openMultipleInstances>false</openMultipleInstances>
                   <decorated>true</decorated>
                   <popupSupported>false</popupSupported>
                   <closeSupported>true</closeSupported>
                   <openAsPopupByDefault>false</openAsPopupByDefault>
                   <excludeFromSavePerspective>false</excludeFromSavePerspective>
                   <paramMap/>
                   <sortIndex>-1</sortIndex>
               </workpageStartInfo>
           </subNodes>
       </subNodes>
   </subNodes>
</workplaceFunctionTreeInfoNode>

Runtime function trees

Customization of logon screen and welcome screen

Authorization Management

Basics

Authorization Object Types

Example

<authorizationType id="CCEntityRights" text="Rights on entity">

    <aspect id="entity" text="Entity" aspectReferenceId="refEntityId"/>

    <aspect id="action" text="Type of action: CREATE/EDIT/DISPLAY" aspectReferenceId="refAuthAction"/>

</authorizationType>

Generated class

package org.eclnt.dataapp.logic.authority;

 

import org.eclnt.dataapp.logic.authorization.*;

 

public class ARCCEntityRights

    extends AuthorizationRequest

{

    public static final String TYPE_ID = "eclnt_dataapp.CCEntityRights";

    public static final String ASPECT_entity = "entity";

    public static final String ASPECT_action = "action";

 

 

    public ARCCEntityRights()

    {

        super(TYPE_ID);

    }

    

    public ARCCEntityRights setEntity(Object value) { addAspectValue(ASPECT_entity,value); return this; }

    public ARCCEntityRights setAction(Object value) { addAspectValue(ASPECT_action,value); return this; }

 

}

Usage in application processing

protected boolean checkAuthorizationForRemoving(BEANCLASS selectedObject)

{

    ARCCEntityRights r = new ARCCEntityRights()

        .setAction(ENUMEditMode.EDIT)

        .setEntity(BCIRuntime.instance().

                   getEntityIdByClass(selectedObject.getClass()));

    return AuthorizationManager.instance().checkIfUserIsAuthorized(r);

}

Interface IAuthorizationManager

Interface

package org.eclnt.dataapp.logic.authorization;

 

public interface IAuthorizationManager

{

    public boolean checkLogon(String user, String password);

    public boolean checkIfUserIsAuthorized(AuthorizationRequest request);

    public void expectThatUserIsAuthorized(AuthorizationRequest request) throws MissingAuthorizationError;

}

Implementation

...

dataapp_authorizationmanagerclassname=org.eclnt.ccda_base.logic.authorization.CCDAAuthorizationManager

...

Default implementation of Authorization Manager

Dependencies

JEE/javax based projects:

 

<dependency>

    <groupId>org.eclnt</groupId>

    <artifactId>ccdabase</artifactId>

    <version>${cc.version}</version>

</dependency>

 

Jakarta based projects:

 

<dependency>

    <groupId>org.eclnt</groupId>

    <artifactId>ccdabase_jakarta</artifactId>

    <version>${cc.version}</version>

</dependency>

Usage

User and Authentication Management

Default User Management

Online Authentication

API Authentication

Upgrading the RapidApp version

Regular updates

Update of your application

    <properties>

        <!-- This is the CaptainCasa version to be used. -->

        <cc.version>20260331</cc.version>

        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    </properties>

Update of your toolset

Adding RapidPDF

RapidPDF is an additional framework by CaptainCasa which simplifies the creation of PDF documents for business objects.

By adding RapidPDF to RapidApp you can...

Extending the pom.xml

Open the pom.xml in the root directory of your project.

JEE projects (“Tomcat 9”)

Add the following dependency to your project dependencies:

        <!-- Printing -->

        <dependency>

            <groupId>org.eclnt</groupId>

            <artifactId>eclntsjrxml</artifactId>

            <version>${cc.version}</version>

        </dependency>

Jakarta EE Projects (“Tomcat 10/11/...”)

Add the following dependency to your project dependencies:

        <!-- Printing -->

        <dependency>

            <groupId>org.eclnt</groupId>

            <artifactId>eclntsjrxml_jakarta</artifactId>

            <version>${cc.version}</version>

        </dependency>

Rebuild and redeploy

After having done the changes:

Defining the print forms

Locate the form definition functions

Open the workplace of your project as administrator: in the “[Admin]” section there is the function tree for the “eclnt_sjrxml” project, that you embedded by having updated your pom.xml:

The most important function there is the “Form editor”.

Editing the form

Information on how to edit the form is available here:

Combining projects

Each project builds its “.jar” artifact

The build of a project is executed by the usage of Maven. Maven uses the “pom.xml” file of the project to execute all build steps. The steps by default include:

You may take a look into the “/target” folder of your project in order to view both files.

The “.jar” file is the one that is used for structuring projects. By simple Maven-dependency you can take over all information of one project into another project.

Example: CaptainCasa default projects “ccdabase” and “ccdaclog”

CaptainCasa uses exactly the “.jar”-structuring to by default provide two projects and add them to your project. The Maven-dependencies are:

<dependency>

    <groupId>org.eclnt</groupId>

    <artifactId>ccdabase_jakarta</artifactId>

    <version>${cc.version}</version>

</dependency>

<dependency>

    <groupId>org.eclnt</groupId>

    <artifactId>ccdaclog_jakarta</artifactId>

    <version>${cc.version}</version>

</dependency>

(For JEE projects: use names without “_jakarta”.)

We recommend to keep these dependencies. The id of all CaptainCasa entity types are starting with “CC” - which is treated as reserved name space.

Referencing entity types and other artifacts