Post-Conversion
To run the sample application please go to Gitpod, and look for the README.md with instructions on how to use it.
In case you want to review the source code of the migrated application, you can find it here: HelloWorld sample code. Also, the migrated code can be downloaded from PBMAPJavaHelloWorld.

Migrated Code Overview

This section explains in detail the following topics:
  1. 1.
    How does the migrated code look like?
  2. 2.
    Which changes were made over the existing code?
  3. 3.
    What are the helpers delivered by Mobilize for?

How does the migrated code look like?

Before moving to explain the output code, first let's take a look at the PowerBuilder sample code:
1
forward
2
global type w_sample from window
3
end type
4
type dw_1 from datawindow within w_sample
5
end type
6
type sle_1 from singlelineedit within w_sample
7
end type
8
type st_1 from statictext within w_sample
9
end type
10
type cb_1 from commandbutton within w_sample
11
end type
12
end forward
13
14
global type w_sample from window
15
integer width = 1266
16
integer height = 844
17
boolean titlebar = true
18
string title = "Untitled"
19
boolean controlmenu = true
20
boolean minbox = true
21
boolean maxbox = true
22
boolean resizable = true
23
long backcolor = 67108864
24
string icon = "AppIcon!"
25
boolean center = true
26
dw_1 dw_1
27
sle_1 sle_1
28
st_1 st_1
29
cb_1 cb_1
30
end type
31
global w_sample w_sample
32
33
on w_sample.create
34
this.dw_1=create dw_1
35
this.sle_1=create sle_1
36
this.st_1=create st_1
37
this.cb_1=create cb_1
38
this.Control[]={this.dw_1,&
39
this.sle_1,&
40
this.st_1,&
41
this.cb_1}
42
end on
43
44
on w_sample.destroy
45
destroy(this.dw_1)
46
destroy(this.sle_1)
47
destroy(this.st_1)
48
destroy(this.cb_1)
49
end on
50
51
type dw_1 from datawindow within w_sample
52
integer x = 73
53
integer y = 256
54
integer width = 1070
55
integer height = 420
56
integer taborder = 20
57
string title = "none"
58
string dataobject = "d_sample_list"
59
boolean livescroll = true
60
borderstyle borderstyle = stylelowered!
61
end type
62
63
type sle_1 from singlelineedit within w_sample
64
integer x = 471
65
integer y = 80
66
integer width = 320
67
integer height = 112
68
integer taborder = 10
69
integer textsize = -10
70
integer weight = 400
71
fontcharset fontcharset = ansi!
72
fontpitch fontpitch = variable!
73
fontfamily fontfamily = swiss!
74
string facename = "Tahoma"
75
long textcolor = 33554432
76
borderstyle borderstyle = stylelowered!
77
end type
78
79
type st_1 from statictext within w_sample
80
integer x = 96
81
integer y = 80
82
integer width = 320
83
integer height = 112
84
integer textsize = -10
85
integer weight = 400
86
fontcharset fontcharset = ansi!
87
fontpitch fontpitch = variable!
88
fontfamily fontfamily = swiss!
89
string facename = "Tahoma"
90
long textcolor = 33554432
91
long backcolor = 67108864
92
string text = "Test Dw"
93
boolean focusrectangle = false
94
end type
95
96
type cb_1 from commandbutton within w_sample
97
integer x = 827
98
integer y = 80
99
integer width = 320
100
integer height = 112
101
integer taborder = 10
102
integer textsize = -10
103
integer weight = 400
104
fontcharset fontcharset = ansi!
105
fontpitch fontpitch = variable!
106
fontfamily fontfamily = swiss!
107
string facename = "Tahoma"
108
string text = "Add"
109
end type
110
111
event clicked;int li_row
112
if sle_1.text <> "" then
113
li_row = dw_1.insertrow( 0)
114
dw_1.setitem( li_row, 1, sle_1.text)
115
end if
116
end event
Copied!
The converted code from the one above will consist of two parts:
  • The Backend code containing the Java files and the helpers .war to emulate the PowerBuilder functionality.
  • The Frontend code with the angular project for the web application.
As the image shown below:
The generated Frontend files are added in the automatically created folder sampleSite-angular, which contains an angular project template and all these converted files.
The structure of this sampleSite-angular folder is as follows:
  • sampleSite-angular
    • src
      • app
        • components
          • sample
            • w_sample
              • w_sample.component.ts
              • w_sample.component.css
              • w_sample.component.html
            • d_sample_list
              • d_sample_list.component.ts
              • d_sample_list.component.css
              • d_sample_list.component.html
            • index.ts
        • app.component.css: stylesheet file used by the app.component
        • app.component.html: html file associated with the app.component
        • app.component.ts: startup angular component of the migrated application
        • app.component.spec.ts: this is the file to include the frontend unit tests
        • app.module.ts: this module includes all the sub-modules of all the application. e.g. You have two projects (pbt): project1.pbt and project2.pbt. This will yield two sub-modules: project1.module.ts and project2.module.ts
        • app-routing.module.ts: this file handles the application routing
        • root.component.ts: required file to define the root component of the application, where all other components will reside
        • sample.module.ts: this module includes all the components of the sample pbt.
      • index.html: this is the page that launches the angular startup component: app.component
      • styles.css
    • package.json: json file that contains the list of JavaScript packages required by the application.
Now let's take a look at these generated components. We will start with the HTML file:
1
Copied!
Every control declared in the w_sample file will have its corresponding HTML tag; for example, the sample application has a Command Button control, so the HTML has this:
1
Copied!
The HTML tag wm-command-button is Mobilize's corresponding Command Button angular component. Mobilize provides a series of angular components which you can use in the future when adding new controls to an existing screen.
Following with these components review, we have the CSS file that matches with the previously reviewed HTML tag:
1
.sample_w_sample .w_sample {
2
width: 279px;
3
height: 211px;
4
background-color: ButtonFace;
5
}
6
.sample_w_sample .dw_1 {
7
position: absolute;
8
left: 5.77%;
9
top: 30.33%;
10
width: 84.52%;
11
height: 49.76%;
12
border-style: solid;
13
}
14
.sample_w_sample .sle_1 {
15
position: absolute;
16
left: 37.2%;
17
top: 9.48%;
18
width: 25.28%;
19
height: 13.27%;
20
font-weight: normal;
21
font-family: Tahoma;
22
color: WindowText;
23
border-style: solid;
24
}
25
.sample_w_sample .st_1 {
26
position: absolute;
27
left: 7.58%;
28
top: 9.48%;
29
width: 25.28%;
30
height: 13.27%;
31
font-weight: normal;
32
font-family: Tahoma;
33
color: WindowText;
34
background-color: ButtonFace;
35
}
36
.sample_w_sample .cb_1 {
37
position: absolute;
38
left: 65.32%;
39
top: 9.48%;
40
width: 25.28%;
41
height: 13.27%;
42
font-weight: normal;
43
font-family: Tahoma;
44
}
Copied!
Every control declared in the w_sample file will have its corresponding CSS properties. For example, properties like facename, width, and height from the Command Button control are mapped into the CSS file like this:
1
.sample_w_sample .cb_1 {
2
position: absolute;
3
left: 65.32%;
4
top: 9.48%;
5
width: 25.28%;
6
height: 13.27%;
7
font-weight: normal;
8
font-family: Tahoma;
9
}
Copied!
Finally, the typescript file consists of an angular component class declaration like the one below, for the window class.
1
import { Component, ChangeDetectorRef, Renderer2, ElementRef, ViewEncapsulation} from "@angular/core";
2
import { BaseControlComponent, LengthConverter} from "@mobilize/powercomponents";
3
import { dataTransfer} from "@mobilize/base-components";
4
@Component({
5
selector : 'sample-w_sample',
6
templateUrl : './w_sample.component.html',
7
styleUrls : ['./w_sample.component.scss'],
8
encapsulation : ViewEncapsulation.None
9
})
10
@dataTransfer(['mobsample_sample_w_sample'])
11
export class w_sampleComponent extends BaseControlComponent {
12
constructor (changeDetector : ChangeDetectorRef,render2 : Renderer2,elem : ElementRef,lengthConverter : LengthConverter) {
13
super(changeDetector,render2,elem,lengthConverter);
14
}
15
}
Copied!
Every window, for example w_sample, should have an Angular Component for the form to be displayed in the browser. This component defines three metadata properties:
  • selector — the component's CSS element selector. This selector tells Angular to create and insert an instance of the component where it finds the tag in a HTML template (e.g 'sample-w_sample')
  • templateUrl — the location of the component's template file. (e.g './w_sample.component.html')
  • styleUrls — the location of the component's private CSS styles. (e.g './w_sample.component.scss')

Which changes were made over the existing code?

Let’s have a look at the converted code found in w_sample.java and Iw_sample.java files.
1
//Iw_sample.java
2
package com.sample.sample.sample;
3
4
import com.mobilize.jwebmap.models.WindowModel;
5
6
public interface Iw_sample extends WindowModel
7
{
8
w_sample.dw_1 getDw_1();
9
void setDw_1(w_sample.dw_1 value);
10
w_sample.sle_1 getSle_1();
11
void setSle_1(w_sample.sle_1 value);
12
w_sample.st_1 getSt_1();
13
void setSt_1(w_sample.st_1 value);
14
w_sample.cb_1 getCb_1();
15
void setCb_1(w_sample.cb_1 value);
16
void doConstructor();
17
void doWMInit();
18
}
19
20
//w_sample.java
21
package com.sample.sample.sample;
22
23
import org.springframework.beans.factory.annotation.Configurable;
24
import com.mobilize.jwebmap.aop.annotations.WebMAPStateManagement;
25
import com.sample.sample.sample.Iw_sample;
26
import com.sample.datamanagers.sample.sample.d_sample_list.d_sample_list;
27
import static com.mobilize.jwebmap.datatypes.ShortHelper.shortOf;
28
import static com.mobilize.jwebmap.conditionals.ConditionalsHelper.isTrue;
29
import static com.mobilize.jwebmap.conditionals.ComparisonHelper.notEq;
30
import static com.mobilize.jwebmap.datatypes.IntegerHelper.integerOf;
31
32
@Configurable
33
@WebMAPStateManagement
34
public class w_sample extends com.mobilize.jwebmap.models.WindowModelImpl implements Iw_sample
35
{
36
public dw_1 dw_1;
37
public dw_1 getDw_1() {
38
return this.dw_1;
39
}
40
public void setDw_1(dw_1 value) {
41
this.dw_1 = value;
42
}
43
public class dw_1 extends com.mobilize.jwebmap.datamanager.DataManagerControl
44
{
45
public dw_1(){}
46
public void doWMInit() {
47
super.doWMInit();
48
this.setX(shortOf(16));
49
this.setY(shortOf(64));
50
this.setWidth(shortOf(235));
51
this.setHeight(shortOf(105));
52
this.setTabOrder(shortOf(20));
53
this.setTitle(getLocalizedText("none"));
54
this.setDataManager(new d_sample_list());
55
}
56
}
57
public sle_1 sle_1;
58
public sle_1 getSle_1() {
59
return this.sle_1;
60
}
61
public void setSle_1(sle_1 value) {
62
this.sle_1 = value;
63
}
64
public class sle_1 extends com.mobilize.jwebmap.models.TextModel
65
{
66
public sle_1(){}
67
public void doWMInit() {
68
super.doWMInit();
69
this.setX(shortOf(104));
70
this.setY(shortOf(20));
71
this.setWidth(shortOf(70));
72
this.setHeight(shortOf(28));
73
this.setTabOrder(shortOf(10));
74
}
75
}
76
public st_1 st_1;
77
public st_1 getSt_1() {
78
return this.st_1;
79
}
80
public void setSt_1(st_1 value) {
81
this.st_1 = value;
82
}
83
public class st_1 extends com.mobilize.jwebmap.models.LabelModel
84
{
85
public st_1(){}
86
public void doWMInit() {
87
super.doWMInit();
88
this.setX(shortOf(21));
89
this.setY(shortOf(20));
90
this.setWidth(shortOf(70));
91
this.setHeight(shortOf(28));
92
this.setText(getLocalizedText("Test Dw"));
93
}
94
}
95
public cb_1 cb_1;
96
public cb_1 getCb_1() {
97
return this.cb_1;
98
}
99
public void setCb_1(cb_1 value) {
100
this.cb_1 = value;
101
}
102
public class cb_1 extends com.mobilize.jwebmap.models.ButtonModel
103
{
104
public cb_1(){}
105
public Integer clicked() {
106
Short li_row = 0;
107
if (isTrue(notEq(getSle_1().getText(), ""))){
108
li_row = shortOf(getDw_1().insertRow(0));
109
getDw_1().setItem(integerOf(li_row), shortOf(1), getSle_1().getText(), "String");
110
}
111
return 0;
112
}
113
public void doWMInit() {
114
super.doWMInit();
115
this.setX(shortOf(182));
116
this.setY(shortOf(20));
117
this.setWidth(shortOf(70));
118
this.setHeight(shortOf(28));
119
this.setTabOrder(shortOf(10));
120
this.setText(getLocalizedText("Add"));
121
this.addToEventList("bnclicked", true);
122
this.addToEventMapper("bnclicked", "clicked");
123
}
124
}
125
@Override
126
public void doConstructor() {
127
this.constructor();
128
this.dw_1.doConstructor();
129
this.sle_1.doConstructor();
130
this.st_1.doConstructor();
131
this.cb_1.doConstructor();
132
}
133
public w_sample(){
134
super ();
135
}
136
public void doWMInit() {
137
super.doWMInit();
138
this.dw_1 = new dw_1();
139
this.dw_1.setName("dw_1");
140
this.setSle_1(new sle_1());
141
this.sle_1.setName("sle_1");
142
this.setSt_1(new st_1());
143
this.st_1.setName("st_1");
144
this.setCb_1(new cb_1());
145
this.cb_1.setName("cb_1");
146
this.setTargetName("sample");
147
this.setLibName("sample");
148
this.setSimpleName("w_sample");
149
this.setName("mobsample_sample_w_sample");
150
this.setWidth(shortOf(279));
151
this.setHeight(shortOf(211));
152
this.setTitleBar(true);
153
this.setTitle(getLocalizedText("Untitled"));
154
this.setControlMenu(true);
155
this.setMinBox(true);
156
this.setMaxBox(true);
157
}
158
}
Copied!
The most relevant changes made to the input code by WebMap framework are:
  • Class declarations: WebMap adds @Configurable and @WebMAPStateManagement annotations upon the class declaration.
    1
    @Configurable
    2
    @WebMAPStateManagement
    3
    public class w_sample extends com.mobilize.jwebmap.models.WindowModelImpl implements Iw_sample
    4
    {
    5
    }
    Copied!
  • Variable declarations: WebMap adds a getter and setter for the variable declaration. For example, Get and Set methods for sle_1 PowerBuilder Single Line Edit component.
    1
    public sle_1 sle_1;
    2
    public sle_1 getSle_1() {
    3
    return this.sle_1;
    4
    }
    5
    public void setSle_1(sle_1 value) {
    6
    this.sle_1 = value;
    7
    }
    Copied!
  • doWMInit method declaration: WebMap adds doWMInit to the w_sample.java. This method initializes the component and sets each component property values.
    1
    public void doWMInit() {
    2
    super.doWMInit();
    3
    this.dw_1 = new dw_1();
    4
    this.dw_1.setName("dw_1");
    5
    this.setSle_1(new sle_1());
    6
    this.sle_1.setName("sle_1");
    7
    this.setSt_1(new st_1());
    8
    this.st_1.setName("st_1");
    9
    this.setCb_1(new cb_1());
    10
    this.cb_1.setName("cb_1");
    11
    this.setTargetName("sample");
    12
    this.setLibName("sample");
    13
    this.setSimpleName("w_sample");
    14
    this.setName("mobsample_sample_w_sample");
    15
    this.setWidth(shortOf(279));
    16
    this.setHeight(shortOf(211));
    17
    this.setTitleBar(true);
    18
    this.setTitle(getLocalizedText("Untitled"));
    19
    this.setControlMenu(true);
    20
    this.setMinBox(true);
    21
    this.setMaxBox(true);
    22
    }
    Copied!
  • Type Mappings: WebMap converts the types of the source code to the corresponding type in the new Web Application. For example, datawindow dw_1 has been mapped to com.mobilize.jwebmap.datamanager.DataManagerControl, and cb_1 Command Button to com.mobilize.jwebmap.models.ButtonModel.
    1
    public class dw_1 extends com.mobilize.jwebmap.datamanager.DataManagerControl
    2
    {
    3
    }
    4
    5
    public class cb_1 extends com.mobilize.jwebmap.models.ButtonModel
    6
    {
    7
    }
    Copied!
  • Internal component classes: WebMap adds an internal class for each component of the window, for example, st_1 internal class added to w_sample.java
    1
    public class st_1 extends com.mobilize.jwebmap.models.LabelModel
    2
    {
    3
    }
    Copied!
All these attributes added by Mobilize let Mobilize's Weaving mechanism know it has to inject some code in compilation time to allow the proper execution of web applications.

What are the helpers delivered by Mobilize for?

The helpers delivered by Mobilize are a set of utilities whose function is to emulate PowerBuilder functionality into Java together with the FrontEnd WebMap part of the application. These helpers are divided into two projects:

Backend helpers

Backend Helpers project contains:
  • The core of your migrator
  • Serialization mechanism
  • Interceptors (AOP)
  • View Models
  • Events and Methods of Windows and Data Windows.
Those libraries represent the core of the PowerBuilder application in the “Java platform”. Also, some libraries providing the link and the control between the data and the Frontend user interface are also found here. Some of those libraries are:
  • Datamanager: a Java Plain Old Java Objects (POJO) implementing PowerBuilder Datawindow object. It provides services such as paged data retrieving and other data operations like insert, delete, update and read.
  • Jasper Reports: a dynamic component that represents a PowerBuilder Datawindow printing view, displayed as a PDF format.
  • Database access: this main component handles data persistence and encapsulates the client business logic in different database engines like Oracle and Sybase. This sub layer will provide services to get access to the persistent mechanism. It will be implemented using Spring JDBC, and it will include a Connection Pooling mechanism in order to improve the application's performance.
  • State management: due to its nature, a PowerBuilder application works under a state-full model. However, a Web application does not work like this. In order to preserve behavior a set of Java classes and some Spring Framework features such as Aspect Oriented Programming (AOP) will provide the Application layer with a state management mechanism.
These helpers are delivered as a war file, so the previous information intends to explain what is contain in them.

Frontend helpers

Backend

Building Backend

In this section, we will explain how to build the backend code, so you can later run the application in your default browser. This section applies if you have the JavaHelpers code or the JavaHelpers jar file.

Converted Code Prerequisites

First of all, in order to compile and execute PBJava migrated application, you need the following software installed in your computer:

Building the Backend code

Add environment variables
To be able to run the migrated project, you must add the following variables to the operating system:
  • oms_dir: any directory where you want to start the file system for your application.
  • JAVA_HOME: Java base installation directory. (prerequisite)
  • CATALINA_HOME: Tomcat installation base directory. (prerequisite)
For Windows Users
  1. 1.
    Press the Windows key and type "environment".
  2. 2.
    Choose the "Edit the system environment variables" option.
  3. 3.
    On System Properties window, press "Environment Variables" button
  4. 4.
    Now, on Environment Variables window, add a new entry for every variable mentioned above.
For Linux Users
  1. 1.
    Open a command prompt window (ctrl + alt + T) and type the following command.
    1
    sudo -H gedit /etc/environment
    Copied!
  2. 2.
    Type your password
  3. 3.
    Edit the text file just opened and add the variables typing: JAVA_HOME=java installation path
  4. 4.
    Save the file
  5. 5.
    Logout and login again
Setting up the Java project
  1. 1.
    Look for the helpers code or helpers.jar previously acquired from Mobilize.
  2. 2.
    Look for the template of WebMAP properties previously acquired from Mobilize, and save it in the created folder SampleConf
  3. 3.
    Look for the connection.properties file previously acquired from Mobilize, and save it in the created folder SampleConf
  4. 4.
    Open Spring Tool Suite
  5. 5.
    Create a new workspace
  6. 6.
    Configure JAVA JDK. Go to Window -> Preferences -> Java -> Installed JREs -> Add -> Choose Java installation JDK folder
  7. 7.
    In the Package Explorer, right click and select the Import option.
    1. 1.
      In the dialog, select Maven, Existing Maven Projects and then Next
  8. 8.
    Select the Java Helpers pom.xml previously downloaded and click OK and then Finish
  9. 9.
    Repeat step 6 for the Sample project and add both ReferenceApplication and Target pom.xml
  10. 10.
    Select the Project Menu, make sure Clean all projects checkbox is selected and press Clean button
  11. 11.
    Right click on ws project on Package Explorer and select Maven -> Update Project -> Select All -> OK Button
  12. 12.
    Configure the Application Property files
Configure Application and Connection Property files
  1. 1.
    Click on Run menu
  2. 2.
    Select Debug Configuration
  3. 3.
    Right Click on Apache Tomcat option on the left pane -> New
  4. 4.
    Select the Classpath tab
  5. 5.
    Click on User Entries
  6. 6.
    Click on Advanced...
  7. 7.
    Click on Add External Folder -> press OK button
  8. 8.
    Select the folder SampleConf (created on above step)
  9. 9.
    Click Apply
ReferenceApplication project
This is the web project where the HTML generated files and the Object State Interceptor are placed. This is the project you have to run to see the web application on your browser.
Target project
This is the migrated code, all the java files, windows and data-windows, generated after the migration are here.
connection.properties file
The connection.properties file is used to specify the database connection configuration. Java Helpers use JDBC API and JDBC drivers to connect and execute queries to the database.
Example of a Sybase configuration:
1
connection.url=jdbc:jtds:sybase://:/
2
connection.username=username
3
connection.password=password
4
connection.driver-class-name=net.sourceforge.jtds.jdbc.Driver
Copied!
webmap.properties file
This file contains configuration entries used by the helpers to run the desired application. In this file you can specify the path for the images that you want to display, language (affect for example decimal places separator according to region), etc.
The line application.appstart=com.sample.sample.sample.sample indicates the module that you want to run.
1
# Configuration file
2
enableUpperCaseResponse=true
3
allowMultipleOpenWindows=true
4
usRegionDateFormat=true
5
images.path=images
6
application.trimSpaces=true
7
application.MaximizeMDI=true
8
locale=en-us
9
application.downloadXls=true
10
application.appstart=com.sample.sample.sample.sample
11
# WindowModel Serialization Custom properties
12
serialize.WindowModel.minBox=true
13
serialize.WindowModel.maxBox=true
14
serialize.WindowModel.windowType=true
15
serialize.WindowModel.windowState=true
16
serialize.WindowModel.titleBar=true
17
serialize.WindowModel.controlMenu=true
18
serialize.WindowModel.toolbarVisible=true
19
# TextModel Serialization Custom properties
20
serialize.TextModel.background=true
21
serialize.TextModel.password=true
22
# Datamanager Serialization Custom properties
23
serialize.DataManager.columnHeader=true
24
serialize.DataManager.header=true
25
serialize.DataManager.summary=true
26
serialize.DataManager.footer=true
27
serialize.DataManager.title=true
28
serialize.DataManager.trailer=true
29
serialize.DataManager.detail=true
30
# Band Serialization Properties
31
# SQLProvider supported provider values OraSqlDataProvider or SybaseSqlDataProvider
32
application.SqlDataProvider=SybaseSqlDataProvider
Copied!

Adding Tomcat Server

  1. 1.
    Go to the bottom of the Package Explorer left pane
  2. 2.
    Right click on Servers
  3. 3.
    Go to New
  4. 4.
    Click on Server option
  5. 5.
    Expand Apache option
  6. 6.
    Select Tomcat v9.0 Server and click Next
  7. 7.
    On Tomcat installation directory click Browse
  8. 8.
    Find your Tomcat folder installation
  9. 9.
    Click Finish

Running the code

Compile the Project
  1. 1.
    Select the Project menu and check the Build Automatically option. This option will build the entire project automatically when a change to any file is detected
  2. 2.
    For a manual build, in each imported project, right + click, select on Run As sub-menu and select Maven build
  3. 3.
    In goals, type "clean install" and press Run.
Setup the Server
  1. 1.
    right + click on the Tomcat server and select Open
  2. 2.
    In Timeouts, change the start to 400 ms for the desired time
  3. 3.
    Save the changes
  4. 4.
    Select the ws project, right + click and select the sub-menu Run As… and then Run On Server
  5. 5.
    Open a web browser and browse http://localhost:8080
  6. 6.
    Right click on ws project
  7. 7.
    Select Properties
  8. 8.
    Scroll down and choose Web project Settings
  9. 9.
    Modify Context root field, changing current value (in this case "ws") to "/"
  10. 10.
    Click on Apply button and then OK (this will change the server context)

Modifying/Extending Backend

In this section we will explain how to modify the migrated code with a practical example. For this exercise, you will add a button on the Backend which opens a second window showing the text "Hello World".

Modifying Backend

First, let's expand the size of the w_sample window, to include the new ButtonModel component.
  1. 1.
    Go to method doWMInit in w_sample.java
  2. 2.
    Modify setHeight property to 400:
    1
    this.setHeight(shortOf(500));
    Copied!
  3. 3.
    On w_sample.java add a new ButtonModel component cb_2
    1
    public cb_2 cb_2;
    2
    public cb_2 getCb_2() {
    3
    return this.cb_2;
    4
    }
    5
    public void setCb_2(cb_2 value) {
    6
    this.cb_2 = value;
    7
    }
    8
    public class cb_2 extends com.mobilize.jwebmap.models.ButtonModel
    9
    {
    10
    public cb_2(){}
    11
    12
    public void doWMInit() {
    13
    super.doWMInit();
    14
    this.setX(shortOf(182));
    15
    this.setY(shortOf(180));
    16
    this.setWidth(shortOf(70));
    17
    this.setHeight(shortOf(28));
    18
    this.setTabOrder(shortOf(10));
    19
    this.setText(getLocalizedText("Open"));
    20
    this.addToEventList("bnclicked", true);
    21
    this.addToEventMapper("bnclicked", "clicked");
    22
    }
    23
    }
    Copied!
  4. 4.
    On method doConstructor add the following line to initializes the new component
    1
    this.cb_2.doConstructor();
    Copied!
  5. 5.
    On method doWMInit initialize and set the name of the new component cb_2
    1
    this.setCb_2(new cb_2());
    2
    this.cb_2.setName("cb_2");
    Copied!
  6. 6.
    On interface Iw_sample.java, add a get and set method for cb_2
    1
    w_sample.cb_2 getCb_2();
    2
    void setCb_2(w_sample.cb_2 value);
    Copied!
  7. 7.
    Finally, add or register the new window on the entry point of the application, sample.java. On method getWindowClassNames(), add the following line before return statement:
    1
    windows.put("w_window1", "com.sample.sample.sample.w_window1");
    Copied!

Extending Backend

After expanding the size of the w_sample window, let's add a new window to the project, like this:
  1. 1.
    On package com.sample.sample.sample add a new java class called w_window1, extending from com.mobilize.jwebmap.models.WindowModelImpl, implementing Iw_window1
    1
    package com.sample.sample.sample;
    2
    3
    import static com.mobilize.jwebmap.datatypes.ShortHelper.shortOf;
    4
    import org.springframework.beans.factory.annotation.Configurable;
    5
    import com.mobilize.jwebmap.aop.annotations.WebMAPStateManagement;
    6
    7
    @Configurable
    8
    @WebMAPStateManagement
    9
    public class w_window1 extends com.mobilize.jwebmap.models.WindowModelImpl implements Iw_window1 {
    10
    11
    }
    Copied!
  2. 2.
    Add a StaticTextModel component to w_window1
    1
    public st_1 st_1;
    2
    public st_1 getSt_1() {
    3
    return this.st_1;
    4
    }
    5
    public void setSt_1(st_1 value) {
    6
    this.st_1 = value;
    7
    }
    8
    public class st_1 extends com.mobilize.jwebmap.models.LabelModel
    9
    {
    10
    public st_1(){}
    11
    public void doWMInit() {
    12
    super.doWMInit();
    13
    this.setX(shortOf(21));
    14
    this.setY(shortOf(20));
    15
    this.setWidth(shortOf(70));
    16
    this.setHeight(shortOf(28));
    17
    this.setText(getLocalizedText("Hello World"));
    18
    }
    19
    }
    Copied!
  3. 3.
    Add w_window1 constructor
    1
    public w_window1(){
    2
    super ();
    3
    }
    Copied!
  4. 4.
    Add the doWMInit and doConstructor method as follows:
    1
    @Override
    2
    public void doConstructor() {
    3
    this.constructor();
    4
    this.st_1.doConstructor();
    5
    }
    6
    7
    public void doWMInit() {
    8
    super.doWMInit();
    9
    this.setSt_1(new st_1());
    10
    this.st_1.setName("st_1");
    11
    this.st_1.setText("Hello World");
    12
    this.setTargetName("sample");
    13
    this.setLibName("sample");
    14
    this.setSimpleName("w_window1");
    15
    this.setName("mobsample_sample_w_window1");
    16
    this.setWidth(shortOf(279));
    17
    this.setHeight(shortOf(211));
    18
    this.setTitleBar(true);
    19
    this.setTitle(getLocalizedText("Window 1"));
    20
    this.setControlMenu(true);
    21
    this.setMinBox(true);
    22
    this.setMaxBox(true);
    23
    }
    Copied!
  5. 5.
    Add clicked event to cb_2 internal class on w_sample.java:
    1
    public class cb_2 extends com.mobilize.jwebmap.models.ButtonModel
    2
    {
    3
    public cb_2(){}
    4
    public Integer clicked() {
    5
    return 0;
    6
    }
    7
    public void doWMInit() {
    8
    super.doWMInit();
    9
    this.setX(shortOf(182));
    10
    this.setY(shortOf(180));
    11
    this.setWidth(shortOf(70));
    12
    this.setHeight(shortOf(28));
    13
    this.setTabOrder(shortOf(10));
    14
    this.setText(getLocalizedText("Open"));
    15
    this.addToEventList("bnclicked", true);
    16
    this.addToEventMapper("bnclicked", "clicked");
    17
    }
    18
    }
    Copied!
  6. 6.
    Add code to clicked event to open the new window. First add the ViewManager property, which manages all about displaying and closing windows.
    1
    @Autowired
    2
    @JsonIgnore
    3
    private ViewManager _viewMng;
    4
    5
    @JsonIgnore
    6
    @WebMAPIgnoreStateManagement
    7
    public ViewManager getViewManager() {
    8
    return _viewMng;
    9
    }
    Copied!
  7. 7.
    Now go to clicked event on cb_2 and add the following code:
    1
    getViewManager().showWindow(new WebMapAtomicReference(new w_window1()), w_window1.class);
    Copied!
    1
    public Integer clicked() {
    2
    getViewManager().showWindow(new WebMapAtomicReference(new w_window1()), w_window1.class);
    3
    return 0;
    4
    }
    Copied!
  8. 8.
    On package com.sample.sample.sample add a new java interface called Iw_window1, extending from WindowModel
    1
    package com.sample.sample.sample;
    2
    3
    import com.mobilize.jwebmap.models.WindowModel;
    4
    5
    public interface Iw_window1 extends WindowModel {
    6
    void doConstructor();
    7
    void doWMInit();
    8
    }
    Copied!
  9. 9.
    Add a st_1 get and set to include the component to the new interface
    1
    w_window1.st_1 getSt_1();
    2
    void setSt_1(w_window1.st_1 value);
    Copied!
  10. 10.
    Now, let's take a look to the final class and interface just added:
    1
    //Iw_window1
    2
    package com.sample.sample.sample;
    3
    4
    import com.mobilize.jwebmap.models.WindowModel;
    5
    6
    public interface Iw_window1 extends WindowModel {
    7
    void doConstructor();
    8
    9
    void doWMInit();
    10
    11
    w_window1.st_1 getSt_1();
    12
    13
    void setSt_1(w_window1.st_1 value);
    14
    }
    Copied!
    1
    //w_window1
    2
    package com.sample.sample.sample;
    3
    4
    import static com.mobilize.jwebmap.datatypes.ShortHelper.shortOf;
    5
    import org.springframework.beans.factory.annotation.Configurable;
    6
    import com.mobilize.jwebmap.aop.annotations.WebMAPStateManagement;
    7
    8
    @Configurable
    9
    @WebMAPStateManagement
    10
    public class w_window1 extends com.mobilize.jwebmap.models.WindowModelImpl implements Iw_window1 {
    11
    12
    public st_1 st_1;
    13
    14
    public st_1 getSt_1() {
    15
    return this.st_1;
    16
    }
    17
    18
    public void setSt_1(st_1 value) {
    19
    this.st_1 = value;
    20
    }
    21
    22
    public class st_1 extends com.mobilize.jwebmap.models.LabelModel {
    23
    public st_1() {
    24
    }
    25
    26
    public void doWMInit() {
    27
    super.doWMInit();
    28
    this.setX(shortOf(21));
    29
    this.setY(shortOf(20));
    30
    this.setWidth(shortOf(70));
    31
    this.setHeight(shortOf(28));
    32
    this.setText(getLocalizedText("Hello World"));
    33
    }
    34
    }
    35
    36
    @Override
    37
    public void doConstructor() {
    38
    this.constructor();
    39
    this.st_1.doConstructor();
    40
    }
    41
    42
    public w_window1() {
    43
    super();
    44
    }
    45
    46
    public void doWMInit() {
    47
    super.doWMInit();
    48
    this.setSt_1(new st_1());
    49
    this.st_1.setName("st_1");
    50
    this.st_1.setText("Hello World");
    51
    this.setTargetName("sample");
    52
    this.setLibName("sample");
    53
    this.setSimpleName("w_window1");
    54
    this.setName("mobsample_sample_w_window1");
    55
    this.setWidth(shortOf(279));
    56
    this.setHeight(shortOf(211));
    57
    this.setTitleBar(true);
    58
    this.setTitle(getLocalizedText("Window 1"));
    59
    this.setControlMenu(true);
    60
    this.setMinBox(true);
    61
    this.setMaxBox(true);
    62
    }
    63
    }
    64
    ``
    65
    Copied!

Frontend

Building Frontend

In this section, we will explain how to build the Frontend code, so you can later run the application in your default browser.

Converted Code Prerequisites

In order to compile and execute the FrontEnd WebMap migrated part of the application, you need the following software installed in your computer:
  • NodeJS
  • Angular Client Framework (version 8). To install open a command prompt and run the following command npm install -g @angular/cli
As the previous examples, we are using the following sample migrated code.

Building the Frontend code

  1. 1.
    Install the Angular CLI, if you haven't already done so.
    1
    npm install -g @angular/cli
    Copied!
  2. 2.
    Install yarn, if you haven't already done so.
    1
    npm install -g yarn
    Copied!
  3. 3.
    Update the npm configuration's registry key by running either of the commands below. This is required to resolve Mobilize's packages.
    1
    npm set registry http://ais-build-w7:81/npm/Frontend/
    Copied!
    or
    1
    npm set registry https://www.myget.org/F/mobilizewebmap/auth/559d63b6-5f30-45eb-8acb-d5f7cb2858bc/npm/
    Copied!
  4. 4.
    Go to productcatalogSite\productcatalogSite-angular folder
  5. 5.
    Open a Command Prompt from that folder
  6. 6.
    Start recovering the node modules by executing this command:
    1
    yarn install
    Copied!
  7. 7.
    Once the packages are successfully recovered, you can build the code.
  8. 8.
    Run the following command for development environment
    1
    npm run build
    Copied!
    The --prod flag is optional, and it is used to produce optimized binaries on production mode.
    1
    ng build --prod
    Copied!
  9. 9.
    The content of the output folder named wwwroot must be copied to ReferenceApplication\src\main\webapp

Modifying/Extending Frontend

In this section we will explain how to modify and extend the migrated code with a practical example. For this exercise, you will add a button on the FrontEnd which opens a second window showing the text "Hello World".

Modifying the FrontEnd

To add elements in an Angular component previously created, you need to add the new element using the corresponding selector. In this case, the selector for a button is wm-command-button, so, in order to add the button cb_2 to w_sample, you need to:
  1. 1.
    Add the following line after cb_1
    1
    Copied!
  2. 2.
    Check the resulting code looks like the one below:
    1
    Copied!
  3. 3.
    Add the corresponding style section for this button in w_sample.component.scss.
    1
    .sample_w_sample .cb_2 {
    2
    position: absolute;
    3
    left: 71.82%;
    4
    top: 9.48%;
    5
    width: 24.28%;
    6
    height: 13.27%;
    7
    font-weight: normal;
    8
    font-family: Tahoma;
    9
    }
    Copied!

Extending the FrontEnd

To add new components, you need to create 3 files in a folder with the same name of the component. This new folder will be added under the Frontend project and it will contain the following files:
  1. 1.
    component.html
  2. 2.
    component.scss
  3. 3.
    component.ts
For the previous window1 example, we are going to create the 3 files like this:
TS file: w_window1.component.ts
1
import { Component, ChangeDetectorRef, Renderer2, ElementRef, ViewEncapsulation} from "@angular/core";
2
import { BaseControlComponent, LengthConverter} from "@mobilize/powercomponents";
3
import { dataTransfer} from "@mobilize/base-components";
4
@Component({
5
selector : 'sample-w_window1',
6
templateUrl : './w_window1.component.html',
7
styleUrls : ['./w_window1.component.scss'],
8
encapsulation : ViewEncapsulation.None
9
})
10
@dataTransfer(['mobsample_sample_w_window1'])
11
export class w_window1Component extends BaseControlComponent {
12
constructor (changeDetector : ChangeDetectorRef,render2 : Renderer2,elem : ElementRef,lengthConverter : LengthConverter) {
13
super(changeDetector,render2,elem,lengthConverter);
14
}
15
}
Copied!
Pay attention to the dataTransfer property since it must be the same as the name set in the doWMinit of the window.
1
this.setName("mobsample_sample_w_window1");
Copied!
SCSS file: w_window1.component.scss
If necessary, you can add the CSS properties for each component here. For the w_window1 in the example, this is the resulting CSS sheet:
1
.sample_w_window1 .w_window1 {
2
width: 279px;
3
height: 211px;
4
background-color: ButtonFace;
5
}
6
7
8
.sample_w_window1 .st_1 {
9
position: absolute;
10
left: 7.58%;
11
top: 9.48%;
12
width: 25.28%;
13
height: 13.27%;
14
font-weight: normal;
15
font-family: Tahoma;
16
color: WindowText;
17
background-color: ButtonFace;
18
}
Copied!
HTML file: w_window1.component.html
The third and final file created for the component, is a HTML that looks like this:
1
Copied!
Some important aspects to consider here are:
  • Validate if the model exists at the beginning of the component
1
Copied!
  • Assign the corresponding model for each control. For Example:
1
wm-window --> [model]="model"\
2
st_1 --> [model]="model.st_1"\
Copied!
After extending and building both backend and frontend, the final result will look something like this:

Debugging

In this section we will show you how to debug the migrated Backend code on Spring Tools and how to use the main debugging features. This section applies if you have the JavaHelpers code or the JavaHelpers jar file.
Once the Backend and Frontend of the sample code are compiled, you need to:
  1. 1.
    Select Window -> Show View -> Servers.
  2. 2.
    Right Click on server in the Servers panel
  3. 3.
    Select Restart in Debug or Debug options.
  4. 4.
    Add breakpoints in your code,
  5. 5.
    Right Click on application
  6. 6.
    Select Debug As -> Debug on Server
  7. 7.
    Finally, you'll see your app running on a browser.

Changing to Debug Perspective

In order to improve the view when debugging, you can change the debug perspective as shown in the following image.

Use conditional breakpoint

Conditional breakpoints allow threads to stop at a targeted line when a condition it's true. To add a conditional breakpoint, follow these steps:
  1. 1.
    Right Click the breakpoint and select Breakpoint Properties.
  2. 2.
    Tick the conditional checkbox under Breakpoint properties.
  3. 3.
    Put the condition as per your requirement in the text area.
  4. 4.
    Click on Ok.

Drop to frame

This feature allows you to choose any frame in the call stack during the debugging, and to set the JVM to start again from the selected level in order to rerun a part of your application. To do this, you have to:
  1. 1.
    Select the stack from where you want to start.
  2. 2.
    Click on the Drop to Frame button in the toolbar of the bug window.