About the Author
Don Young is a founder of InPowerSoft Corporation, which provides cutting edge technologies in database driven applications in Java. Mr. Young is a Long Talk Migrating from Java Swing to RCP/SWT presenter in EclipseCon 2006. He is a frequent contributor to Oracle JDeveloper's articles that is distributed to more than 150,000 professionals monthly. Mr. Young is also a frequent speaker at various regional Oracle User Group on Java Development topics. His seventeen-year career includes Technical Director and Technical Architect of Oracle's CRM division in Telecom and Utility verticals. He also held various technical lead and management positions in Intel, Tektronix and Mentor Graphics. Mr. Young held M.B.A., B.S. C.S. and B.S. E.E. degrees.
Spotlight Features

The Rich Engineering Heritage Behind Dependency Injection

Andrew McVeigh takes us on a tour of the rich heritage behind dependency injection, what it represents, and tells us why its here to stay.

Java, the OLPC, and community responsibility

The "One Laptop Per Child" project has a great device ready to ship, but there's no Java on there. Let's think about working together to put Java on OLPC!

Accelerating Database-Driven Application Development In Eclipse RCP


InPowerSoft Corporation started off in the business of building complex Utility Billing Systems for large utility companies. We created our first generation billing system using Oracle Forms. Several years ago, our customers started to inquire about the use of modern development platforms such as Java and .NET. Prospective customers who needed a multi-million dollar billing solution wanted a technology foundation that would last at least another decade.

We realized that we would need to develop a new version of our product using a new technology stack. Our choices were limited but clear; build a web application like the majority of development has been done for the past 5+ years, or look for a rich-client platform that can provide the level of end-user productivity of Oracle Forms.

Today's rich-client platform has incorporated many features that originally fueled the move towards web-based development. Features such as on-demand application installation (via Webstart or similar technologies) and multi-tier deployments became part of the rich-client platform's native capabilities. These factors combined with the type of user-interface interactivity users are looking for drove us to choose a rich-client platform for our application development.

.NET vs. Java

Having decided to use a rich-client platform as the foundation of our application development, we really had only two long-term, viable frameworks to choose from Microsoft .NET or Java. Aside from one's preference of using proprietary versus open-source technology, both frameworks are arguably equally matched. Both are flexible and provide developers a great development environment.
However, when it comes to developing database-driven applications, a single problem plagues both the .NET and the J2EE frameworks neither delivers the same level of development productivity as Oracle Forms. Despite what critics might say about Oracle Form's antiquated technology, developers can still deliver database-driven applications much faster using Oracle Forms compared to Java or .NET!

What makes Oracle Forms more productive than .NET and J2EE for developing database-driven applications is that it provides a higher level of development abstraction. Consequently, Oracle Forms imposes a much more rigid model for application development. However, the level of abstraction in Oracle Forms and its increased productivity have proven to be a good, time-tested trade off considering its limitations.

We explored the .NET platform, which we found already has many infrastructural supports possibly sufficient to creating Oracle-Forms-like features. Our experience indicated that .NET is just as flexible as any rich-client platform, but its productivity is not comparable to Oracle Forms when it comes to developing database-driven applications. For whatever reason, Microsoft either did not realize this or chose to ignore it over all these years.

With .NET, developers still have to struggle with gluing various parts into a cohesive framework. The .NET data access layer (ADO) is reasonably matured as a straight tabular mapping tool. However, ADO lacks certain features such as automatic version checking found in most object relational (OR) mapping layers (e.g., Hibernate, JDO, and TopLink). ADO .NET is restrictively tabular in nature that maps user interface controls to tables in simplistic ways.

Currently, most internal rich-client applications are developed using .NET or a component-based framework with a simplistic data access layer that ties directly to the underlying ODBC, OLE DB, or JDBC libraries. As JDBC matures over time, a greater percentage of developers will use even the more advanced data objects of JDBC 3 directly.

Make no mistake. You can develop database-driven, rich-client applications in a .NET or similar component framework, but many features found in Oracle Forms cannot be easily constructed. For example, to implement parent-child data-block navigation capabilities would require tedious and serious ad-hoc wiring efforts. Most applications instead join these parent-child tables to a singular denormalized UI control for display. Nowhere to be found are features like automatic query mode. Developers have to hand wire a Search Dialog for each table that is mapped to a UI control. Deployment of the data access object layer to a multi-tier system is mostly non-existent. Even .NET offers no relief despite the fact Microsoft is refocusing effort into this area: http://www.eweek.com/article2/0,1895,1928109,00.asp.

In short, although database-driven applications are prolific in the enterprise world, which demands a set of commonly used constructs critical to database manipulation, Java and .Net technologies have not measured up in standardizing these constructs. Moreover, their lower level of development abstraction leaves the hard work up to the developers, who usually re-invent the wheel time and time again! InPowerForms RCP took a more systematic approach to make these critical constructs available in a consistent way with minimal programming. Please checkout http://www.inpowersoft.com/inpowerformsRCP/index.html to read a list of these constructs in more details.

The Evolution of InPowerForms

In order to meet the challenge and eliminate the painful process for developers to wire up the rich-client front end to the database, we decided to create an innovative product called InPowerForms. We built the first version of InPowerForms in Java Swing on Oracle's ADF (formerly BC4J) database access layer. Oracle contacted us and offered resources to assist us with working out issues to port InPowerForms to their latest release JDeveloper. Oracle has made InPowerForms ADF downloadable with their JDeveloper 10g Release 3.

The InPowerForms framework brings to the Java world a higher level of abstraction and many time-tested features that are found in Oracle Forms. This is a tall order and an incredible achievement for InPowerSoft considering the limited amount of resources we spent on building InPowerForms compared to the time and resources Oracle has invested in building Oracle Forms.

Unlike Oracle Forms, which uses the procedural programming language PL/SQL, InPowerForms uses Java, which is far more powerful, reusable, and flexible; especially at the presentation layer. Another key advantage InPowerForms has over Oracle Forms is that InPowerForms leverages the power of the modern IDEs' advanced programming tools, features, debugging facilities, refactoring capabilities, and code navigation; all these advancements together with rigorous use of OO and programming patterns make InPowerForms surpasses Oracle Forms in development productivity by a large margin. InPowerForms has bridged the gap between Oracle Forms and Java, which is being well received by the Oracle Forms community who are desperately looking to migrate to an Oracle-Forms-like J2EE solution.

InPowerForms on Eclipse RCP

Despite InPowerForms' high productivity, we continue to look for ways to increase InPowerForms' competitive edge. While completing our implementation of InPowerForms on Java Swing and ADF, we came to a crossroads. We recognized two emerging open-source technologies that could launch InPowerForms to even a higher orbit; the Eclipse platform with its powerful RCP architecture and JBoss's Hibernate data access layer.
So we decided to implement a new version of InPowerForms on Eclipse RCP and Hibernate. Despite the twelve months of tedious, back-breaking migration of our original code base in Swing/ADF to Eclipse RCP/Hibernate, we made the right decision.

Eclipse with its plug-in and RCP architectures is hands down the most productive IDE on the market and continues to widen its edge over other IDEs. We recognized that we could increase InPowerForms' productivity simply by leveraging the ever-increasing productivity of the Eclipse platform.

JBoss's Hibernate has become the leading database-neutral data access layer. InPowerForms ADF requires you to run on Oracle. With Hibernate as the data access layer, you can use InPowerForms RCP on any Hibernate-supported database including DB2, MySQL, MS/SQL, Oracle, or many others.

The business impact of using InPowerForms RCP are immediate and can be measurably felt. InPowerForms RCP provides the Eclipse RCP community a pattern-based development platform for creating database-driven applications, such as OLTP applications, that can be created in a fraction of time.

The most critical benefits of InPowerForms RCP are increased speed, reliability, and robustness for developing database-driven applications. InPowerForms RCP saves developers the traditional tedious and error-prone process of wiring Java UI components to JDBC works. At the same time InPowerForms RCP provides an incredibly rich set of functionality with minimal or no additional development effort. InPowerForms RCP can increase developer productivity by at least several times and therefore preclude the need to outsource development to a different country at the expense of poor manageability and business intelligence exposure.

Example: build a mini HR application using InPowerForms

Building an InPowerForms RCP application is no different than building a traditional rich-client application. The development process is extremely regular and declarative in nature. Although InPowerForms RCP is not yet completely declarative, more wizardry, integration with Visual Editor, and smart code generation facilities will be included in subsequent releases that will further leverage the Eclipse platform.

InPowerForms RCP uses the classic Model-View-Controller (MVC) design pattern. InPowerForms RCP applies the MVC design pattern using a Block and other help classes as the controller, few UI Composites as the view, and a Data Source and Hibernate mapping files as the model. We will describe these later in more detail.

Below we will reference a simple Human Resource application called InPowerHR (Snapshot 1) that is built on InPowerForms RCP framework. The demo application InPowerHR demonstrates some of the powerful features of InPowerForms RCP library. We believe it is the simplest possible way for developing database driven applications known to Java world with such rich sophistication. The full details of this example can be found at http://www.inpowersoft.com/inpowerformsRCP/demo/demo.html.

Job Form
Figure 1. Sample HR Application Screenshot

On the left hand side of InPowerHR is the Navigator Tree, which presents an inventory of all the nodes that are available within the application. A node can be a Form, URL, or Java action that can be invoked by the user. Each node can be encapsulated within a folder. These objects can be nested in an arbitrary hierarchy.

The InPowerHR application consists of four Forms (a unit of user interface):Locations, Departments, Employees, and Jobs. Each Form encapsulates a transaction and one or more Blocks. The application also has a Java action, Open All Forms, and a URL, Ips Website.

Underneath the menu is a single, integrated Tool Bar, which is used by all Forms in the application. The Tool Bar enables you to query, navigate, insert, delete, and refresh records within the active Block on a Form. The Tool Bar also enables you to commit or rollback a transaction (i.e., changes to data in all Blocks within the active Form). Both the Navigator Tree and Tool Bar are powerful features included in the InPowerForms framework.

A developer can enable or disable manipulation features at the Block-level. For example, you could disable users from inserting or deleting records in the parent Block on a Form, but enable them to insert or delete records in the child Block.

The InPowerForms framework also enables administrators the ability to configure user capabilities (i.e., privileges) to be applied at runtime depending on the Object, Role, and/or User. For example, an administrator could configure a Form to be read-only, or read-only for certain Roles, or read-only for certain Users.

As easy as 1-2-3

Its time to take a closer look at the code level the process of programming InPowerForms. What we will show is the source code of the InPowerHR application's simplest Form JobForm. There are only three files Jobs.hbm.xml, Jobs.java and JobForm.java that comprise the JobForm. You will be pleasantly surprised that with so little coding, you will achieve so much in sophisticated functionality and so relevant to building your applications! For a more comprehensive illustration of what a Form can do, please take an animated tour at general concepts area on website.

Programming InPowerForms is like following a recipe. In fact, we have patternized twenty plus different variation of Forms and put them in a catalog to shorten the learning curve. In general, there are three distinctive yet simple steps in constructing InPowerForms RCP applications. First, create JBoss Hibernate mapping files. Second, create Data Source objects. Third, create the UI Composites. Each category of Form may have slight variations and some have more complexity than others.

The simplest pattern of a Form is it contains only one Block that ties to a Data Source. JobForm belongs to this pattern. It contains a single block and uses a DbTable composite that is bound to a data source called JobSource. The DbTable displays the following columns: "JobTitle", "Min Salary", and "Max Salary".

We assume that you are already familiar with Eclipse Java IDE and know a little bit about JBoss's Hibernate mapping concepts.

Jobs.hbm.xml
1 <hibernateÐmapping>
2        <class name="com.inpowersoft.hr.biz.Jobs" table="jobs">
3            <id name="jobId" type="long">
4                <column name="JOB_ID"/>
5                <generator class="native"/>
6            </id>
7    
8            <timestamp name="modifiedTime" column="MODIFIED_TIME"/>
9            <property name="jobTitle" type="string">
10               <column name="JOB_TITLE" length="35" notÐnull="true"/>
11           </property>
12           <property name="minSalary" type="com.inpowersoft.common.type.MoneyType">
13               <column name="MIN_SALARY" precision="7" scale="2"/>
14           </property>
15           <property name="maxSalary" type="com.inpowersoft.common.type.MoneyType">
16               <column name="MAX_SALARY" precision="7" scale="2"/>
17           </property>
18       </class>
19   </hibernateÐmapping> 

Step 1. Create Hibernate mapping file

In the mapping file you specify each of the columns to be displayed in the Form along with their attributes. Note that we use MoneyType for the salary fields. The MoneyType is a custom type included in the InPowerForms framework. You can also create and extend your own custom types. Each custom type can have rules for input parsing, validation and presentation.

Jobs.java
3    public class Jobs implements java.io.Serializable
4    {
5      private static final long serialVersionUID = Ð 8564747949857177099L;
6      private long jobId;
7      private String jobTitle;
8      private Money minSalary;
9      private Money maxSalary;
10     private Date modifiedTime;
11   
12     public Jobs()
13     {}
14   
15     public long getJobId()
16     {
17       return this.jobId;
18     }
19   
20     public void setJobId(long jobId)
21     {
22       this.jobId = jobId;
23     }
24   
25     public String getJobTitle()
26     {
27       return this.jobTitle;
28     }
29   
30     public void setJobTitle(String jobTitle)
31     {
32       this.jobTitle = jobTitle;
33     }
34   
35     public Money getMinSalary()
36     {
37       return this.minSalary;
38     }
39   
40     public void setMinSalary(Money minSalary)
41     {
42       this.minSalary = minSalary;
43     }
44   
45     public Money getMaxSalary()
46     {
47       return this.maxSalary;
48     }
49   
50     public void setMaxSalary(Money maxSalary)
51     {
52       this.maxSalary = maxSalary;
53     }
54   
55     public Date getModifiedTime()
56     {
57       return this.modifiedTime;
58     }
59   
60     public void setModifiedTime(Date modifiedTime)
61     {
62       this.modifiedTime = modifiedTime;
63     }
64   }

Step 2. Dervice Jobs.java from Jobs.hbm.xml

Note that you can configure the XML mapping and .java files manually or use the Hibernate tool to auto-generate them.

JobForm$JobSource.java
1  public static class JobSource extends DbSource
2      {
3        public enum Attributes
4        {
5          jobId, jobTitle, minSalary, maxSalary
6        }
7    
8        public String getSql()
9        {
10         return "from Jobs order by jobTitle";
11       }
12   
13       public DataAttribute[] defineAttributes()
14       {
15         return new DataAttribute[] { new DataAttribute(jobId, queryAble, Jobs.class),
16             new DataAttribute(jobTitle, allPermission, Jobs.class),
17             new DataAttribute(minSalary, modifyAble | queryAble, Jobs.class),
18             new DataAttribute(maxSalary, modifyAble | queryAble, Jobs.class) };
19       }
20   
21       public IUiText getUiText()
22       {
23         return HrMessages.instance;
24       }
25     }
Step 2. Implement nested data source class

  • Each data source provides data to a Block.
  • Line 1:  Derive JobSource from DbSource. A data source is always derived from DbSource.
  • Lines 3-6:  Specify the JobSource's Attributes. A data source Attribute is always an enum.
  • Lines 8-10:  Specify a Hibernate query, which could simple or very complex and sophisticated. This query returns the data from the database to the Block.
  • Line 13:  Override the defineAttribute() function to specify the properties of each DataAttribute. A DataAttribute can have one or more of the following properties: queryAble,insertAble,updateAble,required,reference,allPermission,noPermission,modifyAble,insertAbleLookup and modifyAbleLookup. Please refer to the details for the meaning of each property.
  • Line 21:  Return an IUiText object, which is used to format each DataAttribute name with an externalized String for internationalization.

Up until now we have been decoratively specifying many properties. Now we can create the user interface to allow users to interact with the underlying data.

JobForm.java
1 public class JobForm extends Form
2    {
3      public JobForm(Composite parent, FormConstructorArg arg)
4      {
5        super(parent, arg);
6        setFillLayout();
7    
8        Block block = new Block(this, this, HrMessages.getText("Jobs"), new JobSource());
9    
10       DbTable systemParameterTable = DbTable.create(block, block, new UiAttribute[] {
11           new UiAttribute(jobTitle, 0.6), new UiAttribute(minSalary, 0.2),
12           new UiAttribute(maxSalary, UiAttribute.AUTO_SIZE) });
13   
14       block.addPresentation(systemParameterTable);
15     }
16   
17     /* Inner class covered above in Step 2 */
18     public static class JobSource extends DbSource
19     {
20       public enum Attributes
21       {
22         jobId, jobTitle, minSalary, maxSalary
23       }
24   
25       public String getSql()
26       {
27         return "from Jobs order by jobTitle";
28       }
29   
30       public DataAttribute[] defineAttributes()
31       {
32         return new DataAttribute[] { new DataAttribute(jobId, queryAble, Jobs.class),
33             new DataAttribute(jobTitle, allPermission, Jobs.class),
34             new DataAttribute(minSalary, modifyAble | queryAble, Jobs.class),
35             new DataAttribute(maxSalary, modifyAble | queryAble, Jobs.class) };
36       }
37   
38       public IUiText getUiText()
39       {
40         return HrMessages.instance;
41       }
42     }
43   }

Step 3. Create user interface class for form

  • Note that we will ignore lines 18 to 43, since we reviewed it in the data source section above.
  • Line 1:  Derive the JobForm object from the Form object.
  • Line 3:  This is typical of any Form object that has the same constructor signature.
  • Line 5:  This is mandatory for all Forms.
  • Line 6:  Set a layout manager for the JobForm
  • Line 8:  Create and name a Block object and associate it with the JobSource data source.
  • Line 10:  Create a DbTable to display three DataAttributes Ð jobTitle, minSalary and maxSalary Ð from the JobSource data source. These DataAttributes are declared using the UiAttribute object. Also specifiy the relative column width for each DataAttribute to be displayed within the grid table.
  • Line 14:  Add a presentation, which is the tabular gadget, on to the block.

A Word about Data Types

Note that values in salary columns have a currency sign. This is done automatically when you assign the Money data type on the DataAttribute while you are mapping the Hibernate business object. The Money data type also includes an input mask for validation. Editor and renderer for this data type will behave correctly even in the query dialog. InPowerForms RCP comes with a list of commonly used data types as well as providing a mechanism a developer can extend to create their own datatypes.

Conclusion

We have only touch the tip of an iceberg with this article of the full features of InPowerForms. Unlike anything you have seen in developing Java database applications, InPowerForms has raised the bar for database-driven application development and enables developers to operate at a higher level of abstraction. As a result you no longer need to think about how individual UI composites should be wired via JDBC to manipulate the database. You have created a rich, functional JobForm that can provide full manipulation to capture and present data in and out of a database by following a very regular process. As a matter of fact, the development process for most InPowerForms RCP applications is extremely templatized and predictable.

Sophisticated input validations can prevent user input errors as early and responsively as possible before any data is delivered to the database. In addition, a large number of standard constructs in InPowerForms, such as automatic Query Dialog, will not require any coding at all. Furthermore, InPowerForms RCP provides an array of templates that capture  many practical patterns of commonly used Forms, which can accelerate the development process even more. By leveraging this powerful, pattern-based architecture, InPowerForms RCP is setting a new standard in ease of use, flexibility and sophistication for database-driven application development.