Table of Contents

Chapter 2: My first OX project
Create a new project
Configure database
Your first business component
The table
Executing your application
Automating the tests
The labels

Chapter 2: My first OX project

Create a new project

First open your Eclipse and make its workspace the one that comes with the OpenXava distribution.
Using the appropriate Eclipse Wizard create a new Java Project named Management. Now you have a new empty Java project in the workspace, the next step is to give it the correct shape for an OpenXava project.
Go to the project OpenXavaTemplate and edit the file CreateNewProject.xml in this way:
<property name="project" value="Management" />
Now execute CreateNewProject.xml using Ant. You can do it with Right Button on CreateNewProject.xml > Run as > Ant Build
Select the project Management and press F5 for refreshing.
And now you have a new project ready to start working, but before continuing you need to configure the database.

Configure database

OpenXava generates a JavaEE/J2EE application intended to be deployed in a Java Application Server (since v2.0 OpenXava applications also run in a simple servlet container, as Tomcat). In OpenXava you only need to indicate the Data Source JNDI and then configure the data source in your application server. Configuring a data source in an application server is out of the scope of this guide, nevertheless you have below detailed instructions to configure a database in order to run this first project using the Tomcat included in OpenXava distribution as application server and Hypersonic as database. This Tomcat is in the folder openxava-3.x/tomcat.
With Tomcat stopped edit the file context.xml in Tomcat's directory conf. In this file add the next entry:
<Resource name="jdbc/ManagementDS" auth="Container" type="javax.sql.DataSource"
    maxActive="20" maxIdle="5" maxWait="10000"
    username="sa" password="" driverClassName="org.hsqldb.jdbcDriver"
    url="jdbc:hsqldb:hsql://localhost:1666"/>
 
The main thing here is the JNDI name, this is the only thing referenced from OpenXava, in this case ManagementDS. The driverClassName and url attributes depend on your particular database, in this case Hypersonic is used.

Your first business component

Creating an OpenXava business component is easy: The definition of each component is a Java class with annotations. In order to begin you have to create a class called Warehouse:
Now edit your new class and write this code:
package org.openxava.management.model;
 
import javax.persistence.*;
import org.openxava.annotations.*;
 
@Entity
public class Warehouse {
 
    @Id @Column(length=3) @Required
    private int number;
 
    @Column(length=40) @Required
    private String name;
 
    public int getNumber() {
        return number;
    }
 
    public void setNumber(int number) {
        this.number = number;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
}
 
This class contains (and it will be contain) all data needed by the application about the Warehouse business concept. At the moment we only have data structure, but in this class you can put the mapping against the database, the business logic, the visual presentation, the tabular data management, etc.
Really this class is an Entity that follows the EJB3 standard. For defining a class as a entity you only need to use the @Entity annotation in the class declaration.
In entity you define properties, let's see how:
@Id                                  // 1
@Column(length=3)                    // 2
@Required                            // 3
private int number;                  // 4
private int getNumber() {            // 4
    return number;
}
private void setNumber(int number) { // 4
    this.number = number;
}
 
This is its meaning:
  1. @Id: Indicates if this property is part of the key. The key is a unique identifier of the object and usually matches with the primary key of a database table.
  2. @Column(length= ): Length of data. It's optional, but useful to display better user interfaces and generating database tables.
  3. @Required: Indicates if it's required to validate the existence of data for this property just before creation or modification.
  4. The property defined in the usual way for a Java class. All valid types for a Java property are applicable here, including integrated types, JDK classes and custom classes.
The possibilities of the property definition go far from what is shown here, you can see a more complete explanation in Model chapter.

The table

Before testing the application you have to create the table in database. Follow these steps:

Executing your application

After your hard work it is time to see the fruit of your sweat. Let's go.
And now you can play with your module and see its behavior.
Also you can deploy your module as a JSR-168 portlet, in this way:

Automating the tests

Although it seems that the most natural way to test an application is to open a browser and use it like a final user; in fact it is more productive automating the tests, in this way as your system grows, you have it tied and you avoid to break it when you advance.
OpenXava uses a test system based on JUnit and HttpUnit. The OpenXava JUnit tests simulate the behavior of a real user with a browser. This way you can replicate exactly the same tests that you can do directly with an internet browser. The advantage of this approach is that you can test easily all layers of your program from user interface to database.
If you test the module manually you usually create a new record, search it, modify and finally delete it. Let's do this automatically:
First you must create a package for the test classes, org.openxava.management.tests, and then add the WarehouseTest class to it, with next code:
package org.openxava.management.tests;
 
import org.openxava.tests.*;
 
/**
 * @author Javier Paniza
 */
 
public class WarehouseTest extends ModuleTestBase {
 
    public WarehouseTest(String testName) {
        super(testName, "Management", "Warehouse");  // 1
    }
 
    public void testCreateReadUpdateDelete() throws Exception {
        // Create
        execute("CRUD.new");                         // 2
        setValue("number", "7");                     // 3
        setValue("name", "JUNIT Warehouse");
        execute("CRUD.save");
        assertNoErrors();                            // 4
        assertValue("number", "");                   // 5
        assertValue("name", "");
 
        // Read
        setValue("number", "7");
        execute("CRUD.search");
        assertValue("number", "7");
        assertValue("name", "JUNIT Warehouse");
 
        // Update
        setValue("name", "JUNIT Warehouse MODIFIED");
        execute("CRUD.save");
        assertNoErrors();
        assertValue("number", "");
        assertValue("name", "");
 
        // Verify if modified
        setValue("number", "7");
        execute("CRUD.search");
        assertValue("number", "7");
        assertValue("name", "JUNIT Warehouse MODIFIED");
 
        // Delete
        execute("CRUD.delete");
        assertMessage("Warehouse deleted successfully"); // 6
    }
 
}
You can learn from this example:
  1. Constructor: In the constructor you indicate the application and module name.
  2. execute: Allows to simulate a button or link click. As an argument you send the action name; you can view the action names in OpenXava/xava/default-controllers.xml (the predefined controllers) and Management/xava/controllers.xml (the customized ones). Also if you move the mouse over the link your browser will show you the JavaScript code with the OpenXava action to execute. That is execute(“CRUD.new”) is like click in 'new' button in the user interface.
  3. setValue: Assigns a value to a form control. That is, setValue(“name”, “Pepe”) has the same effect than typing in the field 'name' the text “Pepe”. The values are always alphanumeric because they are assigned to a HTML form.
  4. assertNoErrors: Verify that there are no errors. In the user interface errors are red messages showed to user and added by the application logic.
  5. assertValue: Verify if the value in the form field is the expected one.
  6. assertMessage: Verify if the application has shown the indicated informative message.
You can see that is very easy to test that a module works; writing this code can take 5 minutes, but at end you will save hours of work, because from now on you can test your module just in 1 second, and because when you break the Warehouse module (maybe touch in another part of your application) your test warns you just in time.
For more details have a look at the JavaDoc API of org.openxava.tests.ModuleTestBase and examine the examples in org.openxava.test.tests of OpenXavaTest.
By default the test runs against the module in alone (non portal) mode (that is deployed with deployWar). But if you want it's possible to test against the portlet version (that is deployed with generatePortlets). You only need to edit the file properties/xava-junit.properties and write:
liferay.url=web/guest
This is for testing against Liferay. Also it's possible to test against a JetSpeed2 portal, look at OpenXavaTest/properties/xava-junit.properties to learn more.

The labels

Now everything works well, but a little detail remains yet. Maybe you want to define the labels to be show to the user. The way is to write a file with all labels, thus you can translate your product to another language with no problems.
To define the labels you only have to edit the file Management-labels_en.properties in i18n folder. Edit that file and add:
Warehouse=Warehouse
You do not have to put all properties, because the more common cases (number, name, description and a big etc) is already included with OpenXava in English, Spanish, Polish, French, German, Indonesian and Catalan.
If you wish the version in an other language (Spanish for example), you only need to copy and paste with the appropriate suffix. For example, you can have a Management-labels_es.properties with the next content:
Warehouse=Almacén
The OpenXava default labels and messages are in OpenXava/i18n/Labels.properties and OpenXava/i18n/Messages.properties. If you want to override some of these resources you do not need to edit these files, instead, you can use the same key names in the resource files of your project, then your labels and messages will be used instead of the standard ones of OpenXava (new in v2.0.3). For example, if you want to change the standard message in list mode ''There are 23663 objects in list” for other, you have to add to your Management-messages_en.properties this entry:
# list_count is in Messages_en.properties of OpenXava, this is an example
# of overriding a standard openxava message
list_count=There are {0} records in list
Now, your application will show “There are 23663 records in list” instead of the default OpenXava message “'There are 23663 objects in list”.
If you want to know more about how to define labels of your OpenXava elements please look in OpenXavaTest/i18n.