Welcome!

Victor Rasputnis

Subscribe to Victor Rasputnis: eMailAlertsEmail Alerts
Get Victor Rasputnis via: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Related Topics: Java EE Journal

J2EE Journal: Article

HyperText Objects or the PowerBuilder VM Anywhere

HyperText Objects or the PowerBuilder VM Anywhere

Let's face it: we would love to put our PowerBuilder systems on the Web. As the industry trend is to make every new project "Web-enabled," our PB applications have already acquired the word "legacy" in front of them.

With the current efforts to enable remote access and enterprise security, the traditional client/server systems that assumed a concentrated users base in one area are becoming a thing of the past.

We all know the cost of serving our users off the Web: the full-blown redesign of "legacy" systems. This redesign is partially related to the repartitioning of the former two-tier functionality. For instance, all application segments that need access to database and local files have to be replaced by Web services or calls to EJBs deployed on an application server. A much bigger problem, however, is that rewriting a PB application into JavaScript/HTML or Java doesn't allow any reuse of the GUI design and application code behind it. This isn't due to the syntax difference between languages, but to the fact that the entire suite of high-level PowerBuilder controls - the PowerBuilder Object Model - is not supported outside of PB.

Is there an alternative? Sure. Microsoft Internet Explorer, starting with version 5.0, enables the creation of "user objects" in pure JavaScript. It's possible to build counterparts of native PowerBuilder controls on this platform, re-creating their methods, events, and attributes. In other words, it's possible (and relatively simple) to reincarnate PowerBuilder on the Web. Then, putting your existing application on the Web no longer means completely redesigning the system, but rather a smooth port.

In this series of articles we discuss the technology for building and using these HyperTextObjects (HTO) instead of userobjects. We start by rebuilding a couple of simple PB controls. Then we explain how with HTO technology it's possible to rebuild an entire PB Virtual Machine for the Web. Finally, to illustrate the business purpose - that your Web application code can become hard to distinguish from the original PB one - we'll demonstrate the integrated example based on PowerBuilder's Data Explorer demo screen. (In our previous articles, "Converting Your Client/Server Applications to the Internet," [XML-J, Vol. 2, issue 3] and "XMLControl or DataWindow Anywhere," [PBDJ, Vol. 8, issue 3], we covered related topics - the integration of the proposed solution with J2EE/ASP servers and XML as well as with front-end design tools like Dreamweaver.)

Enter the HyperText Objects
HyperTextObject is just a friendly name we came up with to distinguish the proposed architecture and implementation from the underlying technology. It's built on a technology called element behaviors; the word element emphasizes that these JavaScript objects can be presented as custom tags within an ordinary HTML page.

Compared with traditional approaches to building "system" and "user objects" for the Web - Java applets or ActiveXs - an object model built in pure JavaScript offers several major advantages. It doesn't have distribution or security problems, since HTOs are downloaded and rendered automatically as part of the containing Web page. Unlike ActiveX, which has to be coded in C++/VB or applets, with Java Script there are no dependencies on the support beyond the browser (e.g., DLLs or JVM). Behaviors provide a simple single-language scripting development environment for authoring both objects and applications.

The best part is PowerBuilder developers feel instantly "at home" developing and using HTOs. They can define new objects, add properties, events, and methods, drop them on the page using design tools or just include them as simple HTML tags. All in all, PB developers are the most prepared for HTOs.

Due to space constraints, we limit the samples implementation to the IE 5+ browsers. This approach also works on Netscape and Opera browsers with the help of a "Neptune" plug-in from MeadCo Software (www.meadroid.com/neptune/).

Your First HTO
We start with a PowerBuilder groupbox (presented in Listing 1 and Figure 1) as an example of a simple control that doesn't need any events or methods. We found it to be a compelling case, since no matter how simple it is, it doesn't have a counterpart in the HTML standard.

Just as in PB, there are two ways to create custom controls: inheriting from standard objects, or creating a "custom" object (tag) and populating it with other elements. In the first case we could create an instance of groupbox HTO by attaching a certain "behavior" to a standard <SPAN> element:

<span label="Groupbox Label" style="background-color:silver;
position:absolute;top:23px;left:199px;width:200px; height:100px;
behavior:url(groupbox.htc)"/>
In the second scenario, we would declare a custom tag "groupbox" in the <STYLE> section and use it as a standard tag in the HTML page:

<STYLE>pbdj\:groupbox { behavior:url(groupbox.htc);
}</STYLE>
<pbdj:groupbox label="Groupbox Label" style="
background-color:silver;position:absolute;
top:23px;left:199px;width:200px;height:100px"/>
Either way, the corresponding "behavior" file (groupbox.htc) that paints the border and places the label in the appropriate places has to be written. The "definition" portion of this file is:

<-- groupbox.htc file - interface definition-->
<PUBLIC:COMPONENT NAME="GBox" tagName="GROUPBOX">
<PROPERTY NAME="label" ID="label" value=""/>
<ATTACH EVENT="oncontentready"
HANDLER="constructor"/>
</PUBLIC:COMPONENT>
The first line tells us that this behavior services the "groupbox" tag. The next one says that "label" is a public property of that tag and can be used as an object instance variable with the same name inside the control. Finally, we need to know when the tag is fully parsed so we can use our custom "constructor" function to create the required presentation.

The following code does just that. First it inserts a rectangular object with a border between our control and the elements inside (such as child radiobuttons or checkboxes). We do it in such a manner that this <DIV> becomes the only direct child of the placeholder element encapsulating all the original children of the placeholder inside itself:

// adds empty rectangular object with no default visual
var g = document.createElement("DIV");
g.style.border = "2px groove";
element.applyElement(g, "inside");
// All current children of element become children of "g"
// and "g" becomes the only direct child of our element
To add the groupbox label we modify the behavior element by adding <SPAN> with the label's text and positioning:

element.innerHTML+='<SPAN style="position:'+
'absolute;top:0px;left: 10px">'+label+'</SPAN>';
There are other details, of course, such as suppressing external borders possibly styled in our element and preventing a clash for the real estate of our label with the encapsulated children elements, which we omitted here (see Listing 2). Aside from these implementation details, that's all it takes to author groupbox HTO. Simple, isn't it? Let's take it to the next level then.

Creating Checkbox Control
Our next example is a checkbox HTO. HTML Object Model does have a checkbox, or to be more precise, it has <INPUT type="checkbox">. The following shortcomings of the HTML checkbox seemed compelling enough to "upgrade" it to an HTO version:

  • It requires application code to map the checkbox state into database friendly values such as "Y[es]"/"N[o]".
  • It requires application code to maintain the status (modified versus not modified) of the value.
  • It requires application code to create an associated clickable label.
  • An HTML checkbox doesn't support "validation" events and logic.
We want a powerful HTML element that's similar to the checkbox within the DataWindow control with a set of attributes like this:

<checkbox id="cbx_1" value="N" label
onleft="true"
label="Show Details:" onValue="Y" offValue="N"/>
We would also like this element to support onItemChanging and onItemChanged events, the value of the "originalBuffer", and whatever else that takes the burden of mundane work away from the application programmer.

Let's start with control painting. Similar to the groupbox in the previous example, our checkbox would dynamically add presentation elements in the constructor. This time it's a label and <INPUT type="checkbox"> for the purpose of painting the checkbox. For instance, the following HTML is adequate to paint the checkbox with a label "Show Details" located to the left of the checkbox mark:

<LABEL for=cbx_{uniqueID}>Show Details:</LABEL>
<INPUT id=cbx_{uniqueID} type=checkbox />
The uniqueID, uniquely generated by Internet Explorer for each instance of an HTO, can be used anywhere in the JavaScript implementation of the HTO instead of the familiar PowerBuilder "this".

Now, let's look at the events. Usually there are two sides to event implementation: declaring the event and triggering one. To declare onItemChanging and onItemChanged events we put the following lines in the <PUBLIC:COMPONENT> section:

<PUBLIC:EVENT NAME="onItemChanging"
ID="onItemChanging" />
<PUBLIC:EVENT NAME="onItemChanged"
ID="onItemChanged" />
HTO can use these events to notify the client page that the value is about to change or has already changed. However, it needs to provide event parameters - newValue, for example. We might also need to communicate to the control that changes are accepted or rejected. Whenever the user clicks on a checkbox, the control has to execute code similar to this:

//... UI checkbox sends in newValue
//current value is kept in origValue
var message = createEventObject();
message.newValue = newValue;
onItemChanging.fire(message);
if (message.returnValue != 1 ) {
origValue = newValue;
onItemChanged.fire();
}
The Message object we created first is equivalent to the global "message" object in PowerBuilder. We just need to pass the newValue to the application - the current value is still unchanged and is available as a property of the control. Application code can reject the change by setting the returnValue attribute on the Event to 1.

Please note the convenience of this JavaScript object versus the PowerBuilder one. First, you can "stack" event objects and trigger events from events without clashes on the global event object. Second, with JavaScript objects we're not limited to any predefined number or type of parameters (Number, String, PowerObject). We don't have to declare structures to decode the contents of PowerObjectParm. Everything is truly dynamic: we're free to attach any attributes and objects and we have direct reference to them on the receiving side.

The application code that wants to use these events can use event handlers. The event object becomes a property of the global window object and can be a referenced window.event. We cover the issue of the separation of JavaScript code from the HTML presentation shortly.

function checkbox_1::onItemChanging() {
if (!{validation logic})
...// some logic
window.event.returnValue=1; //revert change
}
Now let's implement HTO methods. Again, we need to declare a method and then we have to provide a script for the method's implementation. The following lines added to the <PUBLIC:COMPONENT> section provide method declarations for Hide() and Show():

< PUBLIC:METHOD NAME="Show" ID="Show"/>
< PUBLIC:METHOD NAME="Hide" ID="Hide"/>
For the functions' implementation, we delegate it to a CSS "visibility" attribute:

<SCRIPT>
function Show() {style.visibility='visible';}
function Hide() {style.visibility='hidden';}
</SCRIPT>
Finally, to implement HTO properties we also start with a declaration within the <PUBLIC:COMPONENT> section:

<PUBLIC:PROPERTY NAME="label" />
<PUBLIC:PROPERTY NAME="checked" GET="getChecked"
PUT="putChecked" />
The "checked" property here is an example of a property in which specific actions (functions getChecked() and putChecked()) need to be executed when a property value is assigned or read.

The full code of the HTO checkbox is shown in Listing 3. As you can see we created a full-blown user object with properties, events, and methods with the same amount of code it would take to create a similar object in PowerBuilder. It does take some time to adjust to the new syntax, but the important part - OO design, events, and delegation - are virtually identical.

Encapsulation
The two HTOs presented above share one common shortcoming: the internals of implementation are fully open to outside code. The global JavaScript variables of these controls fall into the global scope of the document they're included in. This is dangerous enough as we run into the possibility of name clashes: the most obvious case is more than one instance of the same control. In addition, the HTML of these objects is transparently included in the HTML document of the "master." Not only does this present more name-clashing danger, it also makes our control's code unsafe as it can reference outside objects and vice versa.

To put it simply, a special mechanism is required to enable a truly modular approach in object authoring. Fortunately, the HTO technology supports an intelligent solution, viewLink, to this problem.

There are two ways objects can be marked as viewLink. It can be done via declarations within the <PUBLIC:COMPONENT> section:

<PUBLIC:DEFAULTS viewLinkContent/>
Or it can be done in the code with the following line of JavaScript code:

defaults.viewLink = document
Objects that are marked as viewLink are highly encapsulated; each has its own HTML document tree and its internals are "invisible" to the master document. Every instance of the object has its own set of instantiated values and only public methods and properties can be accessed by the outside code. In other words, the viewLink mechanism fully enables the design and implementation of sophisticated Web applications using a true OO component-based approach.

Conclusion
In this article we briefly described the "evolutionary" approach to the redeployment of PowerBuilder applications on intranets and the Web using the J2EE environment. It's based on the substitution of native PB objects with HyperText Objects. More information, as well as the online implementation of the DW2Java conversion tool, can be found at www.xmlsp.com, which is maintained by the authors.

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 vrasputnis@faratasystems.com

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.