Welcome!

PowerBuilder Authors: Chris Pollach, Yeshim Deniz, Jayaram Krishnaswamy, Kevin Benedict, Avi Rosenthal

Related Topics: PowerBuilder

PowerBuilder: Article

Deploy Your PowerBuilder Applications On The Web

Deploy Your PowerBuilder Applications On The Web

The ability to deploy applications on the Internet or intranet has become essential for application development, especially when developing new applications with Internet/J2EE-compatible tools. For PB developers this meant that instead of a single high-level integrated environment, they had to use low-level tools and a multitude of languages and technologies, and write more code while delivering less functionality. The problem became even more apparent when they needed to transfer existing applications to the Web.

As we'll see in this article, this is no longer the case. Deployment to the Web/intranet no longer means a complete rewrite of the application. Rather, it's a painless conversion process with changes only in the areas pertaining to the platform, not in the application code/functionality domain. In this article we will demonstrate how to deploy existing DataWindows (which in PB projects requires most of the development effort) on the Web with virtually no rewriting.

At the heart of the proposed solution is the XMLControl - an incarnation of the DataWindow for the Web. It provides similar functionality and is 100% Java/ JavaScript/XML/XSL based. This article highlights features of XMLControl that are important to application developers. It also describes the automatic deployment of legacy DataWindows as XMLControls on any J2EE application server including EAS, WebLogic, SilverStream, and WebSphere. For more implementation details, see our article, "Leveraging XML," in the March edition of XML-Journal (Vol. 2, issue 3).

Simple Report
Let's start with a simple example - an HTML page displaying a report from the "employee" table of the sample database EASDemoDB (see Figure 1). This page contains just one XMLControl. In PowerBuilder it would be a window containing a single DataWindow. The following is the HTML for our page in Internet Explorer 5:

<html>
<head>
<style>
.XMLControl
{behavior:url(/common/bcc/XMLControl.btc)}
</style>
<script for="window event="onLoad">
dw_1.connectionPool = "samplePool"; dw_1.retrieve();
</script>
</head>
<form id="dw_1" class="XMLControl" dataSource="employeeRoster"></form>
</html>

Let's look closely at this HTML page. It contains a single instance of XMLControl named "dw_1":

<FORM id="dw_1" class="XMLControl" dataSource="employeeRoster"></FORM>
A PowerBuilder analog of this form would be a DataWindow control that's associated with a "d_employee_roster" data object. The DataSource property points to a set of application server objects that are responsible for populating the XMLControl dw_1. We'll cover the construction of DataSource objects later in the article. For now, think of the DataSource "employeeRoster" as very similar to the DataWindow's data object, "d_employee_roster" - driving the population of data buffers, setting up initial filter and sort values, and more.

The actual data retrieval occurs after the page is loaded. Script corresponding to the "onLoad" event invokes an asynchronous method retrieve():

dw_1.connectionPool = "samplePool";
dw_1.retrieve();
This is done the same way you'd populate a DataWindow in the "Open" script of a PowerBuilder window:
dw_1.SetTransObject(SQLCA)
dw_1.retrieve()

The slight difference here is that a client/server transaction object is replaced with a reusable connection and allocated off the application server's connection pool.

As you can see from the above HTML, the implementation of XMLControl is packaged as an IE behavior - XMLControl.htc. Behaviors became available in IE5.0, which was also the first IE version to support XML. If we "upgrade" our HTML to the level of IE 5.5, we'll be able to use a dedicated custom tag, "xmlsp:XMLControl", instead of <FORM>, improving readability of the code:

<html xmlns:xmlsp>
<head>
<?IMPORT namespace="xmlsp" implementation="/Common/htc/menu.htc"/ >
<script for="window" event="onload">
dw_1.connectionPool = "samplePool"; dw_1.retrieve();
</script>
</head>
<xmlsp;XMLControl id="dw_1" dataSource="employeeRoster"/>
</html>
This example also demonstrates built-in support for pagination and navigation from one data page of XMLControl to another. In our case, with employee data grouped by department, every group starts on a new page. XMLControl automatically inserts a customizable navigation bar at the bottom of the screen, as in Figure 1.

Simple Data Entry Form
XMLControl can be used for more than just reports. Similar to PowerBuilder's DataWindow, XMLControl treats data entry forms and reports seamlessly. It's all controlled by a DataSource element - the same way it's always been controlled by a data object in a DataWindow. To illustrate the data-entry capabilities of XMLControl, we'll use another example, also based on the EASDemo database. The HTML page displays data from the "contact" table (see Figure 2). The XMLControl's DataSource in this page is set to "contactMaintenance":

<xmlsp:XMLControl id="dw_1" dataSource="contactMaintenance" />
In fact, the above DataSource was automatically generated from the editable "d_contact_maintenance" found in the PB demo application. (The automatic conversion of DataWindow data objects into DataSource and the deployment of DataWindows as XMLControls is discussed later.)

Generated DataSource resulted in rendering to the browser <INPUT> tags wherever the original d_contact_maintenance contained a nonzero value for "Tab Order" on a column, thus supporting user input into the fields. What makes this page different from the previous one, though, is the presence of three extra buttons - "Add," "Delete," and "Update."

<IMG src="add.gif" onClick="dw_1.insertRow(dw_1.getCurrentRowId())" />
<IMG src="delete.gif" onClick="dw_1.deleteRow(dw_1.getCurrentRowId())" />
<IMG src="update.gif" onClick="dw_1.update();" />

As you can see, functions insertRow() and deleteRow() operate on the ID of the current row, rather than on the display position of it, as in the DataWindow's case. It's also worth mentioning that the update() function communicates data changes to the application server for execution rather than to the database. And, unless XMLControl subscribes to a specific persistent server transaction, update() function results in an attempt to COMMIT/ROLLBACK all data changes within one XMLControl as a single unit of work. Short of these nuances, XMLControl's API should be familiar and easily acceptable by any PowerBuilder developer.

XMLControl API
Table 1 presents an abridged list of the supported properties, methods, and events of the XMLControl API. The data manipulation part of the XMLControl API contains acceptChanges(), resetUpdate(), getItem(), and setItem() methods in addition to the retrieve(), update(), deleteRow(), and insertRow() methods described earlier. All these methods are similar to their counterparts in PowerBuilder.

The navigational part of the XMLControl API contains the getCurrentRowId() used in the latest example, as well as setRow(), scrollToRow(), scrollToFirstRow(), selectRow(), getNextSelectedRow(), and isRowSelected(). In addition, it includes doFilter(), doSort(), setFilter(), and setSort() functions. The latter two accept XSL Xpath expressions for filter and sort operations. This departure from PowerBuilder syntax is caused by the very nature of XMLControl, which keeps all data in XML format, providing functionality far beyond a flat two-dimensional data buffer.

Events fired on XMLControl include onEditChange, onItemChanging, onItemChanged, onPaintBegin, onPaintEnd, onRowFocusChanging, onRowFocusChanged, onKeyDown, and onUpdateError.

DataSource Demystified
Now we'll demystify the DataSource to the extent allowed by space in the article. Readers can get additional details from our article in XML-Journal.

In one statement, the DataSource is a base name for a set of J2EE application server objects that support the functionality described in the traditional PowerBuilder data object. Naturally, the anatomy of a DataSource is easy to explain by comparing it to a DataWindow's data object. As a reminder, a data object defines how a result set is mapped to the database, what it should look like on screen, and what computations, filtering, and sorting it should go through prior to being displayed. But the data object is nothing without the PowerBuilder Virtual Machine behind it. Here lies the key difference between DataWindow and XMLControl architectures. The DataSource objects needn't be interpreted by a proprietary VM. Once generated and deployed, these objects start a life of their own in any J2EE server.

In particular, one of the DataSource objects - a Java servlet - returns requested database data in XML format. (Thus, a data model is human readable and easy to work with.) Another object, XSL stylesheet, formats XML data for browser rendering. Functionality, supporting client-side computations such as conditional attributes, totals, and other aggregations, is embedded in JavaScript file(s). We developed a free online conversion tool, named "DW2Java," that automatically generates and deploys all these objects in a J2EE server, given the Powersoft report files (PSR) of a particular DataWindow. The logical flow of this "DataObject-to-J2EE-Objects" conversion is shown in Figure 3.

Creation of DataSource Objects
The generation of DataSource objects or, depending on how you look at it, the conversion of legacy DataWindows to a J2EE environment, is a one-step process.

Let's make a sample generation of the "employeeRoster" DataSource used in our first example. We can use "d_print_employee_roster_dw" from the PB sample application. We'll save it as a PSR file on a local drive, say "c:\employeeRoster.psr". It's advisable to retrieve some real data prior to saving the PSR if we're going to bypass the servlet when testing the results against the static XML file that DW2Java generates off that data.

The direct Internet address of the online version of the DW2Java conversion tool is www.xmlsp.com/DW2Java.htm (see Figure 4).

After filling in an e-mail and the full path of the PSR we submit it for conversion by clicking on the "Next" button. That's all it takes to create and deploy the servlet employeeRoster.class, the stylesheet employeeRoster.xsl, and the JavaScript file employeeRoster.js. (See Table 2 for the full list of "employeeRoster" DataSource files.) It doesn't get any easier than that.

Power to the Client
While designing the XMLControl, we wanted to fully retain the robust client-side capabilities of the DataWindow. Yet we didn't want to penalize the user with an extra round-trip for any sort/filter actions or recalculations of computed values.

As a solution we persisted XML data within the HTML page, where it can be accessed directly by the JavaScript. And it's also within the page where the transition to DHTML from XML (known as XML "transform") happens.

C++ and Java programmers heavily utilize the Model/View/Controller architecture. It means that the data (Model) is independent from the presentation rules (View) and is "visually merged" by presentation behavior (Controller). XMLControl is based on this architecture: XML data is the Model, XSL stylesheet is the View, and the placeholder DHTML is the Controller.

Current implementation relies on Internet Explorer, which, at the time of this writing, is the only browser that's 100% compliant with the W3C recommendations on XML and XSL support. IE continues to gain market share, surpassing 87% of Internet users, according to the latest survey published by WebSideStory, Inc. (www.websidestory.com), and is the de facto standard for intranet business applications.

Getting Advanced: Master/Detail
and Data Sharing We've shown that XMLControl completely separates data from presentation. Data in XML format is provided by a Java servlet, while presentation is handled with an entirely different object - an XSL stylesheet. As a result, data sharing between instances of XMLControl is even more powerful and flexible than it was with DataWindows. For example, consider a page that enables a user to browse through customer records and edit the details (see Figure 5).

The following JavaScript is the only code needed for this page to function (see Listing 1 for the full HTML of the page).

main.shareData(detail);
main.singleRowSelection = true;
master.retrieve( );

detail.setDynamicFilter("@selected='true'");

As you can see, this data-sharing technique is quite similar to a standard PB one. In addition, the singleRowSelection attribute controls row selection and highlighting capabilities, something that in the glorious days of the PFC would be called a row selection service. It's worth mentioning that the setDynamicFilter() method provides presentation-only filtering that's not matched by PowerBuilder's DataWindow. In the case of a DataWindow, filtering (or sorting) of the master control was immediately hitting the buffer, thus affecting the detail. In XMLControl architecture there are two ways to filter/sort: traditional, where the data model (buffer) is affected, and dynamic, where stylesheet information (loaded in memory) is modified prior to "transform."

Overall, XMLControl provides extra flexibility and incorporates many framework-type functions that are naturally expected in modern PB applications.

Print Preview Mode and Advanced Printing
DataWindow's "Print Preview" mode enables users to see the "printed" version of the report. Until recently, however, only specialized ActiveX-based solutions such as Acrobat Reader and specialized reporting packages such as Actuate provided similar functionality on the Web.

This situation changed when Internet Explorer 5.5 introduced print-preview architecture out of the box. Every page, browsed in IE 5.5, can be opened in "Print Preview" mode. Unfortunately, reports printed with default browser settings can hardly be accepted by business users: pages breaking in unwanted places, headers and footers displaying irrelevant (to business) information.

XMLControl provides a "turnkey" solution for business-level "Print Preview" functionality. For our Print Preview functionality use the following function call:

xmlControl.enablePrintPreview ([yourCustomTemplate])

To revert to the default browser's implementation use:

xmlControl.disablePrintPreview ()
Figure 5 shows the "employeeRoster" report in "PrintPreview" mode. Note: We added "Actual Size," "Page Width," and "Full Page" buttons "borrowed" from Acrobat Reader to the standard "Print Preview" toolbar of Internet Explorer.

XMLControl handles print preview based on the "print templates" approach provided by IE (see Figure 6). Print templates are essentially HTML files that control the page layout and printing flow. The universal printing templates of XMLControl automatically recognize header, group, detail, and footer bands and ensure they're placed properly in the "hard copy" layout. In addition, they guarantee that only the report (and none of the surrounding HTML elements including other frames, etc.) is being viewed and printed.

XML Metadata "Describes" It All
As shown in Figure 3, XML metadata plays a central role in the conversion of DataWindows into J2EE objects. However, XML metadata is just as valuable at runtime, providing information obtained in PB via the "Describe" function.

Figure 7 presents a generic-sort dialog (built-in in XMLControl) running against "Customer List" metadata, with the records sorted by "Last Name, First Name".

Making this dialog user-friendly required access to the business names of the columns. We also needed data types to make sure we were invoking the right type of sorting. Similarly, the built-in "Filter" or "Query-By-Example" dialogs must be required knowledge of the appropriate presentation, such as whether a particular column is a checkbox, an edit field, or a selection list. This information is contained in the metadata and is available for custom enhancements. The appropriate XMLControl methods to bring up these built-in functions are showSortDialog(), showFilterDialog(), and showQueryDialog() accordingly.

Server-Side "Roots" of XMLControl
XMLControl is, by its very nature, a "distributed" object, in the sense that a large part of it works on the application server and requires server support. Here's a brief glance at the server-side "roots" of XMLControl.

As a communications protocol, XMLControl relies on Simple Object Access Protocol (SOAP), the XML-based, "over-the-HTTP" protocol. With SOAP you don't have to be concerned with firewall and accessibility issues. What makes it a winner over binary ones - DCOM, RMI, or CORBA - is that it's cross-platform and extensible, and can be understood by any server that "talks" HTTP.

XMLControl deploys validation and update code as EJBs. It creates wrapper JSP for EJBs to be called from the client. It also creates a WSDL (Web Services Description Language) file that allows the browser/client to enumerate available functions and get data-type information and a list of the arguments.

XMLControl provides a "gateway" to the server's Web services. It allows EJB server object methods - validation and update are the most frequent examples - to be accessed by the client JavaScript. All security, packaging, binding, and marshaling occur transparently to the application code.

Summary
In this article we briefly described the "evolutionary" approach to the redeployment of PowerBuilder applications on intranets and the Web using a J2EE environment. It's based on the automatic conversion of DataWindow objects into J2EE ones with cutting-edge Internet technologies. As a result, most of the PB-specific application code becomes "Internet-enabled" with just minor cosmetic changes. More information, as well as a free online implementation of the DW2Java conversion tool, can be found at www.xmlsp.com.

More Stories By Victor Rasputnis

Dr. Victor Rasputnis is a Managing Principal of Farata Systems. He's responsible for providing architectural design, implementation management and mentoring to companies migrating to XML Internet technologies. He holds a PhD in computer science from the Moscow Institute of Robotics. You can reach him at [email protected]

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.