These pages describe the 'bpm4struts' cartridge. The shorthand 'bpm4struts' stands for 'Business Process Modeling for Struts'. The purpose of this cartridge is to generate Struts web pages from an input UML model in which the flow of the application is modeled.
Writing a web front-end for J2EE application can become a really cumbersome and tedious task. Most of the time it is very difficult to start with a good design and keep it, the problem may even become more apparent when multiple developers are working on the same project. In a Struts application more specifically, problems that often arise are: too much data in the session, bad variable names in the pages and in the actions, inconsistent programming style, improper exception handling, hard-coded constants, duplicated code, and the list goes on...
The reason these issues exist is not always because the developers are inexperienced or lazy; the main reason is that it is simply very difficult to keep everything consistently up-to-date. It is very easy to lose track of what is going on and before you know little evil parts of code find their way in, introducing bugs and making maintenance a pain.
It is important to keep an eye on the big picture. Take a look at your application from a distance, maybe you'll spot some design flaws. This brings us to the most common tools for communicating application architectures: the Unified Modeling Language, unfortunately not many people believe in it ... and that's understandable, it can be quite a burden to keep the UML model up-to-date (*) when you are already facing the many issues mentioned above; the Model Driven Architecture paradigm solves this problem elegantly, read on.
(*) This is already where it is going wrong, your model should exist before you even start coding, but since development is an iterative process and changes are often applied in the code first we find ourselves updating the UML model to comply with these changes.
A second comment is that at all times a developer should spend his efforts on the core business of the application, if he's writing an online web-shopping application he should not be worrying about coding connection pooling or a search engine, this should be reused from elsewhere. There is so much activity in the open-source community that this should not be a problem anymore.
So, if it would be possible to quickly generate the desired code from a UML model using coding templates, and to regenerate this code without losing any manually applied changes, one can easily see the benefits: a constant focus on the overall design, the developer can try several different approaches in a short time interval, the developer spends his time on the business logic and not on the technologies used to achieve his goals.
As you will read in this document bpm4struts addresses the majority of these items.
We aim to have a means of generating a stable and flexible Struts front-end by modeling dynamic business processes from UML. The transformation from UML to Struts should be open enough to allow anybody to easily update this process, for example by simply editing some templates.
Any feature provided by Struts should also be available in the cartridge.
The generated code should be consistent and in-line with the most common best-practices in web development. It must also help the user adding the final pieces of code in order to finish the implementation. Except for the business logic he will need to implement himself, the user should not need to have knowledge of the rest of the generated application, although it can never hurt.
Regeneration of code from UML should not overwrite manually written code. Classes can attain this goal by using a construction such as inheritance. With JSPs we use Tiles to isolate those pieces that need regeneration, anything else remains untouched.
When a complete application has been modeled it should be possible to generate and deploy the application without any further changes to the code. The application should work right-away, this allows the user to test-drive and see if it is what he expected, optionally updating the model where necessary.
From a UML model bpm4struts is used to generate a fully deployable web application. Complete with a security implementation, validation rules (client & server), exception handling and page forwarding. These features are all available and easily updatable via the UML model.
The generated files include:
Struts will automatically load the appropriate resource bundle for your localization (l10n) and internationalization (i18n) settings whenever available.
Bpm4struts will generate a default resource bundle generated in the language used for modeling. In order to port this file to another language you will need to simply:
For each user there will be a role, depending on the use-cases associated to that user he will gain the privileges to access that use-case's resources and call the corresponding actions.
Users can inherit roles from each other, a user that inherits from two other users will be assigned a role which has the accumulated privileges of the roles from both other users.
Per request sent by the client to the server it is possible to specify the validation rules for the included parameters. The appropriate Javascript functions will be rendered to handle this validation. This will avoid unneccessary calls to the server.
In case for some reason an invalid parameter format would arrive at the server the user will be returned to the page of origin with a message indicating what went wrong.
For each action it is possible to forward exceptions to a specific page. By default, however, all exceptions are forwarded to the page where the action call was triggered, a suitable message will be shown.
Thanks to the combined use of tiles and CSS it is possible to abstract the style & layout from the content of the pages. All pages will be rendered in a similar style, it will be sufficient to update or extend the existing style in order to customize the look and feel of the application.
A very common feature in web pages is the displaying of tabular data. Bpm4struts directly supports this feature through the use of the 'displaytag' tag library. You will be able to have control over the following features:
For each page an online help will be generated that is accessible from a link somewhere on the page (typically at the bottom). The information is gathered from the documentation entered in the UML model.
To make it easier when navigating through a use-case, breadcrumbs will be rendered on screen. For each action/page traversed in the the use-case and breadcrumb will be present, allowing you to go back if needed. Going back will post a copy of the original request.
In order to be able to deploy the generated application without the need for manual editing we made it possible to have a dummy implementation generated. It will make sure that the parameters used between the client and the server are populated with dummy data. This way you can check out your application without needing to code one single letter.
It has always been a burden to properly format dates but bpm4struts makes all of this completely transparent for the user. When a date is needed on screen the proper conversion will be taken into account (which of course can be overridden if desired). It is even possible to have a calendar popup rendered next to the JSP input field, allowing you to easily select a date from the calendar and have if be properly formatted on selection.
When developing a web front-end you must be aware that it is nothing like your regular Swing/GUI development, such as in a standalone application. The HTTP protocol is stateless by design, while most users want to have the feeling they are in a session or context.
There are many ways to solve these typical problems on the web front-end. Personally, I prefer not to make use of the session in the web container: I like to do as much as possible in the scope of the requests. This has several advantages: bookmarks always work, the back button will not corrupt any session data, etc... This is important to know when modeling for the bpm4struts cartridge, it allows you to look at each use-case separately and treat them as individual processing units. You will also notice you tend to write better code this way.
Unfortunately this will render some features impossible to implement. Using only request scope you will have a problem displaying the JSP pages when you are referring them directly instead of going to an action first. An example of this occurring is when Struts declaratively handles an exception, in this case it needs to directly forward to a JSP page. There are two reasons for this:
Consider this scenario, it might make things more clear:
What happens if there are beans on this page that cannot be found in the request ? If you want to go to the action prior to the JSP page, are you sure you can always determine which one it is ?
So you see, it is not so evident trying to have all forms in the request scope only. So for this reason I have decided to switch to session scope. This also has some advantages for performance and sometimes it will conveniently prefill input fields from the same use-case. Of course a possible disadvantage is that you might see input field values you are not allowed to see (application security). But this is easy to remedy and will be features in bpm4struts (probably by removing the form from the session once the use-case finishes, by reaching one of its final states; or alternatively, when entering a new use-case all previous form are removed from the session)
Next, we need to consider the communication between the client and the server, what tools to we have at our disposal ? Well, quite enough I must say ... we can use almost any feature we can find in a rich standalone GUI client: radiobuttons, textareas, hyperlinks, tooltips, and so on. So it would be nice if we can render the appropriate input elements for the request parameters sent from the JSP page.
In order to adhere to the spirit of Struts web development I am trying to attain at least the same strict requirements of its MVC implementation. As opposed to earlier version of this cartridge, you will only need to model the Controller class, the Views and Models are implied by the dynamic processes.
The model corresponds to the form bean used in the request, this bean encapsulates all request parameters for the use-case. No more logic should be put in there. Models are generated by looking at the parameters sent between action states.