XView4Struts -- An Extension to the Struts Framework

Version 1.4.1 Stable

The goal of this project is to make project development easier and faster. If you are familiar with the Struts framework you know that a considerable amount of time is spent implementing the various taglibs, figuring out each tag's idiosynchrosies, learning to work around them and communicating your methodologies to other team members. Normally, the java developer is responsible for implementing the tags and/or the html presentation. Wouldn't it be better if the presentation layer was just pure html? Now it can be.

It is a common practice in many organizations to create a mock-up of an application and use it to solicit client approval before they start working on the underlying logic that makes it work. Wouldn't it be nice to be able to take the mock-up and use it as is with very little to no modifications?

Experience shows that anywhere from 20 to 40 percent of the development time can be used up developing the presentation layer in a Struts environment. Just browse the Struts mail archives and you'll find that many of the problems are related to implementing the taglibs. Additional analysis indicates that the standard set of tag libraries does not meet everyone's requirements. This has led to development of several tag lib packages each with thier own set of rules. XView4Struts attempts to illiminate all the confusion by providing a view layer that anyone with html experience can develope and a Struts interface that has very few rules to implement.

Whether the developer writes the presentation layer or it is the responsibility of a graphics department, very little to no knowledge of the underlying logic is required. In fact you can tell the graphics gurus "Just give me a tag with an id and I'll figure out what to do with it".

The XView4Struts extension attempts to totally seperate the presentation layer from the logic. This is exactly what a good MVC model is suppose to do. It does this by parsing the html source and matching up the tag ids with formbean properties. Each tag has a built-in set of rules that XView4Struts applies to determine how the formbean properties affect that tag. The extension then generates a new page with all of the dynamic properties plugged-in and sends it to the client. The whole process is completely automatic and needs no programic intervention. The developer only needs to concentrate on business and data layer logic. None of the Stuts model or controller functions are affected in any way. This extension may be installed into an existing aplication with absolutely no affect on existing presentation, JSP or HTML, pages.

Installation is straight forward and only requires a couple of steps.
  1. Copy the xview4struts.x.x.x.jar to the lib directory of your project.
  2. Copy the openxml-1.2.2.jar to the lib directory of your project.
  3. Open the struts-config.xml file and make the following entry;
      <!-- ========== Controller Configuration ================================ -->
        <controller processorClass="org.xview.action.RequestProcessor" />

Thats it. You're done. Lets get programming.

HTML and ActionForm Interaction

In this section I will explain how the various HTML elements interact with the form bean's properties. I purposly tried to keep this interaction as simple as possible which means you will not have quite as much flexibility with choosing the form bean property's data types to as you do with the normal Struts environment. Nesting of elements has also been kept to a minimum. Hopefully you will agree with this approach as it tends to reduce confusion and ultimately leads to faster development time.

If an element or a specific variation of an element is not in the list below then the parser simply ignores the tag. If an element is shown below but is not displayed in bold, then the element has not been implemented yet. Just because the parser does not handle a particular element or it doesn't handle it the way you want, don't fret. There is one element that has been implemented that is extremely powerful. It allows you to insert any kind of text, HTML or otherwise, programatically. Be sure you read carefully the description of the "div" tag.

The one general rule that applies to all HTML elements is that you will use the element's "id" attribute to associate an element to a beam property.

The INPUT Tags
<input type="text" id="beanProperty" />
<input type="password" id="beanProperty" />
<input type="hidden" id="beanProperty" />
<input type="checkbox" id="beanProperty" />
<input type="radio" id="beanProperty" />
<input type="submit" id="beanProperty" />
<input type="image" id="beanProperty" />
<input type="file" id="beanProperty" />
id The name of your form bean's property.
value Optional. The parser will create this attribute if it doesn't exist.
If it does exist, the parser will replace it.
Struts bean
The bean property's type must be String. or applicable TagBean.

<textarea id="beanProperty" />
id The name of your form bean's property.
Struts bean
The bean property's type must be String or TextAreaTagBean

<select id="beanProperty" value="" />
id The name of your form bean's property.
value Optional. The parser will create this attribute if it doesn't exist.
If it does exist, the parser will replace it.
Struts bean
The bean property's type must be String or SelectTagBean

<option id="beanProperty" />
idThe name of your form bean's property.
Struts bean
The bean property's type must be Array.
If the array's element is of type String. then only the option's label will be applied.
If the array's element is of type LabelValueBean then the option's value attribute and label will both be applied. LabelValueBean.java is a standard bean distributed with Struts.
If the array's element is of type OptionTagBean then all attributes populated in the tagBean will be applied.

Only one option tag is required. If the html page was originally used as a mock-up, then only the first option tag should use the "id" attribute. All other existing option tags will be replaced.

The IMG Tag
<img id="beanProperty"><img/>
idThe name of your form bean's property.
Struts bean
The bean property's type must be ImageTagBean or ImageTagBean.

The ImageTagBean is a custom bean with properties for every possible IMG attribute. The developer only needs to populate the properties needed.

The Anchor Tag
<a id="beanProperty"><a>
idThe name of your form bean's property.
Struts bean
The bean property's type must be LinkTagBean.

The LinkTagBean is a custom bean with properties for every possible Link attribute. The developer only needs to populate the properties needed.

The DIV Tag
<div type="text" id="beanProperty" />
<div type="url" id="beanProperty" />
<div type="url" id="page.html" />
<div type="xsl" id="beanProperty" />
<div type="errors" id="" />
<div type="message" id="request attribute key" />
textThe parser will insert the bean property's String replacing any existing text.
urlThe parser will insert the contents of the relative or absolute HTML file replacing any existing text.
xslThe parser will insert the results of an xsl transformation replacing any existing text.
errorsA replacement for the Struts tag <html:errors>
messageA replacement for the Struts tag <bean:message>
id The name of your form bean's property.
Struts bean
textThe bean property's type must be of type String.
urlName of a html file must be of type String.
xsl - idName of a xsl file must be of type String.

div Tag -- XView's Powerhouse

The div tag as implemented in this extension is by far the most powerful and dynamic tag implemented. You may still use div tags as intended by the HTML standard. This extension just adds functionality.

The div tag is used to identify an insertion point for HTML document fragments. The document fragment may be simple text, HTML text, the contents of a specified file or the results of an xsl transformation. The document fragment will also be parsed. If the fragment contains HTML elements recognized by the parser then they will be treated as if they are part of the original document. Therefore it is possible to nest any number of document fragments providing the ability to create highly dynamic content. The div tag can also serve as a replacement for the Struts tags <html:errors> and <bean:message> tags.

One possible use of this concept is to create templates for your application. The most popular layout for webpages is to supply a header that may or may not include a menu, a menu on the left hand side, a details section that displays all of the information that gives this page purpose and a footer. Two to three of these sections are relatively constant throughout the application. No one likes having to create the same code over and over again. Maintenance is also a hassel in a project like that because one small change has to be copied to many pages. Then came templates. Templates allow the developer to create a section just once and include it on as many pages as they want. There are several ways to implement the template concept in Struts and XView also provides a mechanism through the use of the div tag. See the section below on using templates.

In practice, any dynamic page content will need a div tag. So if you need to produce a variable length table, a dynamic list of items, display different text for different users or periodically publish different text then you will need to use a div tag. How you implement the div tag is completely up to you. The implementation of this tag is flexible enough that there is normally more that one way to acomplish the same goal.

Inserting Content From Another Page The div tag provides an option to merge multiple html pages into a single page. It is the "type=url" option that performs this function. This option simply extracts all of the content found between the "body" tags of the specified document. After the contents are inserted into the parent document, control is returned to the parser and the new contents are parsed just as if they were part of the original document. In this way, any number of pages may be nested to produce the desired effect. One application of this technique is in creating a templating system.

Using Templates -- An Example
  1. The first step is to create an html page for each section of your layout. So you might create a Header.html, a Menu.html and a Footer.html page.
  2. Create a template page next. This page will have four div tags on it. One for each section. It is also common practice to use a table to layout each section.
  3. On the form bean, define four String variables, one for each section that identifies the html page to be inserted.
  4. Now create the details section.

Implementing this concept means you now have only one page that your application references; the template page and the details are dynamically added as the user navigates your site. The first annoyance that you will run accross is that each navigation point has its own form bean which means that the same four variables have to be included in every form bean and these variables have to be initialized.

There is a work around to this situation.
  1. First create a base ActionForm that defines the header,menu, detail and footer variables.
  2. Next you will need to initialize the header, footer and menu variables. There are several methods you could use to do this. You could set default values or create a static initializer. The idea is that these three properties are relatively constant throughout the application and so you want some automatic method of initialization whenever the form bean is loaded.
  3. For each navigation point, create a details bean that extends the base ActionForm. Think of a navigation point as each complete page presented to the user.
  4. Each Action class that causes a new form bean to be created, needs to initialize the details variable. If an Action is reusing a formBean in session, there is no need for this step unless you are changing the details section of the template. Also note that you can change any of the other sections manually as needed.
With this scheme, you'll have total flexibility over your presentation.

This is just a basic illustration. You will need to adjust it to your own situation. Since Version 1.4.1, it is possible to reduce the requirements placed upon the formbean by using the option that specifies the target html as a context relative path in the id attribute.

XSL Transformations
Many times the nature of the dynamic content comes in the form of data that needs to be prestented in tabular form or as a list. The developer has two options available. One way is to write a method that formats the data as html text, store it in the form bean and use <div type="text"> to display the data.

Another option that could be more usefull is to use the <div type="xsl"> tag. Using this option requires two steps. Populate a custom bean with your data and then write the xsl file.

XView4Struts provides helper classes to facilitate this type of presentation. The class org.xview.parse.helpers.XmlTableBean will probably work for many cases when using this option. It's function is the hold the data. The data may be a simple list of Strings or a two dimensional table stored as a list of org.xview.parse.helpers.XmlRowBean objects. XmlTableBean has a properties that also must be set. The "list" and "table" booleans indicate the type of data structure. These two properties interact inversely with each other so only one, your choice, needs to be set. The xslFileName property needs to be populated with the context relative path to the xsl file that will be used to perform the transformation. The developer is also free to write their own bean. The only requirement is that it implements the XmlBean interface. It is therefore possible to to create beans with any type of data structure, properties and behavior need to achieve the desired behavior.

Refering to the example application, you'll see how easy it is to populate the XmlTableBean. The example also has xsl files you may be able to use as is, with slight modification or at the very least use them as a basis for writing your own xsl files. Many times these xsl files may be used for several pages within a single application. When you think about it, this is a very powerfull concept.

Displaying errors
XView4Struts provides a replacement for the Struts <html:errors> tag. To display a list of errors use <div type="errors">. This tag will display all action errors identified with the key = "ActionErrors.GLOBAL_ERROR". This is a slight deviation from the way Struts does it. In Struts all action errors, reguardless of it's key, is displayed when the <html:errors> is used. If the "id" attribute is present, then only the specified error message will be displayed without the header, suffix, prefix or footer messages.

Displaying messages and internationalization
XView4Struts provides a replacement for the Struts <bean:message> tag. To display a list of messages retrieved from the applicationResources.properties file use <div type="message">. This implementation will display all messages identified with the key = "ActionMessages.GLOBAL_ERROR". This tag will replace any existing text between the <div> and the </div> tags in the html file. To display a specific message use <div type="message" id="xxx">. Just like in the errors implementation, this tag deviates slightly from the Struts implementation.

Cache Manager
XView4Struts provides a cache manager that greatly improves your application's response time. In general, there are two bottlenecks with any web application. They are file I/O and data I/O. Since XView4Struts only deals with the view layer, it can't do much to improve data I/O. Since the html and xsl documents used by XView4Struts are static in nature it makes since that if a master copy is maintained in memory then the file I/O bottleneck would be greatly reduced. There are always tradeoffs. On one hand performance goes up and and processor activity remains more constant. On the other hand, memory useage also increases.

The cache manager is very flexable. It uses the CacheManager.properties file for its configuration. It may be completely disabled. The developer may choose to exclude certain files, define a default keep-alive time or specify keep-alive times on a file by file basis. There is a timer thread that runs in the background that periodically removes all items from the cache that have expired. The thread's frequency is specified in the CacheManager.properties file. You decide what is best for your situation. Another note of importance is that whenever the application access a cached item, it's date value is updated. In this way, active pages are kept im memory longer and less active pages expire sooner.

The cache manager may also be used by developers for virtually any Java object. Just build a CachedItem object and use the CacheManager's static methods to add and remove them to the cache as needed. The developer needs to keep in mind that these objects are globally available. One implication of this fact is that its concievable to cache some data layer objects. So if used in this way XView4Struts can help reduce some data I/O activity.

TagBean Helper Classes
Since Version 1.4, TagBean helper classes were introduced to add more dynamic control over the static presentation tags. TagBeans offer the developer the opportunity to dynamically set any or all attributes associated with a specific tag. TagBeans also act as a place holder for the value property associated with form tags. The value property will be populated by struts when a form is submitted. The value property is also used by XView4Struts to prepopulate a tag when a page is being rendered.

During the rendering process, the TagBean will be inspected for any attributes that have been assigned some value. If such an attribute exists in the TagBean then that attribute will be applied to the tag overwriting any existing attribute. The overall end-effect is that any html tag attributes in the original document will remain unchanged unless over written by an attribute in the TagBean.

The introduction of the TagBean facilitated the addition of another attribute that controls the visibility of a tag. The visibility attribute if set true will prevent the html tag from being rendered.

This table specifies the helper class name that is associated with each html tag.
HTML Tag TagBean Class Name
Input type=text org.xview.parse.helpers.TextInputTagBean
Input type=password org.xview.parse.helpers.PasswordInputTagBean
Input type=checkbox org.xview.parse.helpers.CheckedInputTagBean
Input type=radio org.xview.parse.helpers.CheckedInputTagBean
Input type=image org.xview.parse.helpers.ImageInputTagBean
Input type=submit org.xview.parse.helpers.ButtonTagBean
Input type=file org.xview.parse.helpers.FileTagBean
TextArea org.xview.parse.helpers.TextAreaTagBean
Select org.xview.parse.helpers.SelectTagBean
Option org.xview.parse.helpers.OptionTagBean
Anchor/Link org.xview.parse.helpers.LinkTagBean
Img org.xview.parse.helpers.ImageTagBean

Additional Notes about TagBeans
SelectTagBean:The valueSelected property is of type String[]. This is necessary to make this bean compatible with 'select' tags that have the "multiple" attribute set. For single select 'select' tags you only need a String property as a place holder for the value selected by the user. Multiselect 'select' tags require a String[] to hold all of the values selected by the user. If you use a String[] for a single select 'select' tag, Struts will populate the first element with the selected value. Since a String[] works for both instances then String[] is a perfect fit for the SelectTagBean.
Option Tags:The combinations of 'select' tag formBean property types and 'option' tag formBean property types provides the developer with nine seperate possibilities they may choose from. There are three types for the 'select' tag; String, String[] and SelectTagBean. Internally, the SelectTagBean uses a String[]. The 'option' tag also offers three options; String[], LabelValueBean[] and OptionTagBean[]. When XView4Struts builds a page to be presented to the user it needs to be able to indicate which options of a 'select' tag are preselected. The method for doing this is to populate the 'select' tag's formBean property with the value of the option or options to be displayed as preselected. When using the OptionTagBean, the developer has another method available for displaying preselected options. The developer may choose to set the "selected" attribute of each OptionTagBean individually.

Getting Help
Your best resource for learning how each of these tags are implemented is to review the examples application. If you need additional help then you should use the forums on the XView4Struts website.