How Does <b-frame/> Work?

1. The Architecture
2. An Example
3. The Application Layer
4. The Implementation Layer
5. The Application

1. The Architecture

<b-frame/> is a framework to assist the development of business (i.e. transactional client server) applications. The backbone of such an application typically is a (relational) database, and applications created with <b-frame/> are distributed applications for manipulating the database or another enterprise information system (EIS).

Usually the structure of the application and the database is determined by an analysis process which results in identifying so called business classes. Sometimes it is assumed that these business classes exhibit some kind of behavior; this view is not shared by <b-frame/>, for <b-frame/> these business classes are just plain data. Instead <b-frame/> introduces the notion of a task, which is something you may also call a use case. A task is some kind of a tool being able to manipulate the plain data.

The following figure sketches the <b-frame/> architecture.

Figure 1:   The <b-frame/> architecture.

The <b-frame/> architecture consists at least of the following layers:

Currently <b-frame/> itself provides the Core and Implementation Layers. Maybe in the future these two layers will be unbundled and Implementation Layers other than the one for creating J2EE applications will be available.

To make things clearer, let's take a look at an example.

2. An Example

The example is taken from university's life and consists of two business classes, Institute and Professor.

Figure 2:   Institutes and Professors.

The following assumptions are made:

Provided this information is available from the Application Layer, <b-frame/> is able to create a full blown J2EE application as shown in the following figure.

Figure 3:   The Institute Task with the nested Professor Task.

How the example's Application Layer looks like comes next.

3. The Application Layer

If you're developing with <b-frame/>, you have to provide the Application Layer. But as you will discover soon, there's not a lot to do, only the following two files are needed:

Following is the database descriptor from the above example.

<?xml version="1.0"?>

<bf-db:tables xmlns:bf-db="http://www.b-frame.org/b-frame/db">

<bf-db:table name="institute">
  <bf-db:primary-key name="institute_pk">
    <bf-db:attribute name="name" type="string" length="32"/>
  </bf-db:primary-key>
</bf-db:table>

<bf-db:table name="professor">
  <bf-db:primary-key name="professor_pk">
    <bf-db:foreign-key name="prof_ref_inst" ref="institute">
      <bf-db:attribute name="institute_name" label="Institute Name"
          type="name"/>
    </bf-db:foreign-key>
    <bf-db:attribute name="id" label="Professor ID" type="integer"/>
  </bf-db:primary-key>
  <bf-db:attribute name="name" label="Professor Name"
      type="string" length="32"/>
  <bf-db:attribute name="salary" label="Salary" type="integer"/>
</bf-db:table>

</bf-db:tables>
Listing 1:   The <b-frame/> database descriptor.

If you're familiar with databases and SQL, reading the database descriptor should be straight forward. It defines two tables, Institute and Professor. Note that the Professor table has a foreign key pointing to the Institute table.

The application descriptor defines the structure of an application operation on the database defined by means of the database descriptor.

<?xml version="1.0"?>

<bf-app:application
    xmlns:bf-app="http://www.b-frame.org/b-frame/app"
    name="university3a">

<bf-app:task table="institute">
  <bf-app:task table="professor">
    <bf-app:group type="list">
      <bf-app:field name="id" label="ID"/>
      <bf-app:field name="name" label="Name" link="true"/>
    </bf-app:group>
  </bf-app:task>
</bf-app:task>

</bf-app:application>
Listing 2:   The <b-frame/> application descriptor

The example's application descriptor defines the Institute Task having a nested Professor Task. Note that Professor Task's select list is customized by means of the <bf-app:group> tag, whereas the one from the Institute ask is not. Having the <bf-app:group> tag not defined for a task will result in an application listing the primary key, which is the default.

Now let's take a look behind the scenes.

4. The Implementation Layer

The Implementation Layer is a set of XML templates ready to be merged with information from the Application Layer to result in Java classes, Java Server Pages (JSP), tag libraries, J2EE deployment descriptors, or whatever is needed to constitute a full blown J2EE application.

As an example consider the template for a value object, a simple container for sending data between client and server. The following is responsible for encapsulating one entry from a task's select list.

<bf:java-source xmlns:bf="http://www.b-frame.org/b-frame">
<bf:task>

<bf:group type="list">package <bf:root-package/>.common;

import java.sql.*;

public class <bf:id/>ListVO extends <bf:id/>KeyVO {<bf:fields set="vo-minus-pk">
    public String <bf:field-name/>;</bf:fields>

    public <bf:id/>ListVO(ResultSet rs) throws SQLException {<bf:fields set="vo-union-pk">
        this.<bf:field-name/> = rs.getString("<bf:field-name/>");</bf:fields>
    }
}
</bf:group>

</bf:task>
</bf:java-source>
Listing 3:   The template "list_vo.xml".

The template is Java code with embedded XML tags. The responsibility of the Core Layer is to expand these tags according to the Application Layer. How this expansion for the above example looks like, comes next.

5. The Application

An instance of the template is needed for each of the tasks. From the Application Layer <b-frame/> has enough knowledge to do the job.

package university3a.institute.common;

import java.sql.*;

public class InstituteListVO extends InstituteKeyVO {

    public InstituteListVO(ResultSet rs) throws SQLException {
        this.name = rs.getString("name");
    }
}
        
package university3a.institute.common;

import java.sql.*;

public class ProfessorListVO extends ProfessorKeyVO {
    public String name;

    public ProfessorListVO(ResultSet rs) throws SQLException {
        this.institute_name = rs.getString("institute_name");
        this.id = rs.getString("id");
        this.name = rs.getString("name");
    }
}
Listing 4:   The Institute and the Professor instances of the template "list_vo.xml".