Flux - The Smart Struts Config Generator

The Flux project
SourceForge.net Logo

Generator Mapping Logic

The following sections describe the mapping rules Flux applies to generate the new version of struts-config-<module>.xml from the UML model and the old version of struts-config-<module>.xml.

General Principles

Flux only writes between the opening <action-mappings> and the closing </action-mappings> tag. This means, it creates, changes and deletes only  <action> elements (and comments). All preceding and succeeding parts of the struts-config-<module>.xml are copied unchanged from the old to the new version. Especially, Flux does not perform any checks for consistency between potentially declared form beans or the like and the action mappings that might or might not reference those.

Flux physically (re-)creates all <action> elements freshly on each run. However, if a created <action> element already exists with the same path attribute in the old version of struts-config-<module>.xml, all its attributes and all its nested elements are preserved from the old version as long as they do not contradict the current version of the UML model. Copying the old values is logically equivalent to updating those <action> elements concerned. On the other hand, <action> elements that exist in the old version of struts-config-<module>.xml but which have a path that cannot be re-generated from the current model are practically deleted (as a measure of precaution or as a workaround for situations where special action mappings are needed that cannot be adequately modelled those mappings are in fact moved to the section 'Non-modelled Action Mappings' rather than being physically deleted!).

The default configuration of Flux creates seven logical blocks of <action> elements and introduces each of them with a comment. Additionally, an introductory comment with a timestamp is written before any action mapping:

<action-mappings>
  <!--Generated by de.matthias_burbach.flux.StrutsConfigGenerator at Sat Jun 07 07:41:17 CEST 2003-->
  <!--Page Events--> 
	...
  <!--Action Activities--> 
	...
  <!--Module Activities--> 
	...
  <!--Page Preprocessings--> 
	...
  <!--Page States--> 
	...
  <!--Final State--> 
	...
  <!--Non-modelled Action Mappings-->
        ...
</action-mappings>

The next sections give details on what goes in these six blocks of action mappings.

Page Event Mappings

If one of two or more page events is to be sent through the same HTML form to the application server the form should be coded similiar to the following pattern:

<form name="myForm" action="/Page.<Name>" method="GET" enctype="application/x-www-form-urlencoded">
	...
	<input type="image" name="<Event_1>" src="..."/>
	<input type="image" name="<Event_2>" src="..."/>
</form>

As a consequence, the URL the browser requests on submit of the form does not directly address the action to be triggered in the path. Instead, an image coordinate parameter codes the triggered event. This might look roughly like the following:

http://www.myserver.de/myapp/<Module>/Page.<Name>?...<Event_1>.x=...

Sometimes, depending on your HTML requirements, a similar URL syntax where the event is coded as a parameter called 'action' (or likewise) might be appropriate:

http://www.myserver.de/myapp/<Module>/Page.<Name>?...action=<Event_1>...

Both types of URLs would not match the action mappings described further below. Therefore, Flux generates a special action mapping for each logical page that dispatches the page URL to the respective action URL. To do so the framework class configured as  'Framework Dispatcher Action' is set into the type attribute:

<action path="/Page.<Name>" type="de.matthias_burbach.strux.DispatcherAction" parameter="*.x,action">
  <forward name="<Event_1>" path="/Action.<Name_1>.do"/>
  <forward name="<Event_2>" path="/Action.<Name_2>.do"/>
  ...
</action>

See the edit rules to check what and how you may or may not edit in this type of generated action mapping.

Page Mode Variable Feature

If you make use of the page mode variable feature one further level of indirection will be generated from the page state. To transform the externally used page name which is a concatenation of the internally used page name and the current value of the page mode variable into the internally used page name one additional dispatcher mapping per variable value is generated.

Example:
If you define a logical page with the variable 'mode' accepting any of the values 'Demo', 'Test', or 'Real' three 'pre-dispatcher' mappings will be generated. They transform the composite of logical page name and variable value into a path basically consisting of only the logical page name plus the variable assignment 'mode=<value>' behind the question mark.

<action path="/Page.BalanceDemo" forward="/Page.Balance.do?mode=Demo" />
<action path="/Page.BalanceTest" forward="/Page.Balance.do?mode=Test" />
<action path="/Page.BalanceReal" forward="/Page.Balance.do?mode=Real" />

So any request issued from the logical page 'Balance' will first go through one of the above mappings before reaching the following standard mapping:

<action path="/Page.Balance" type="de.matthias_burbach.strux.DispatcherAction" parameter="*.x,action">
    <forward name="close" path="/Action.Close.do" />
</action>

Action Activity Mappings

For each modelled UML action activity Flux generates a Struts <action> Element of the following syntax:

<action path="/Action.<Name>" ...>

If such an <action> element is created for the first time, i. e. it does not yet exist under the same path in the old version of the struts-config-<module>.xml, then Flux adds a default type attribute and optionally a default name attribute, too.

If, however, it already existed before Flux preserves all old allowable attributes unchanged. The attributes 'forward' and 'include' are not allowable because Flux enforces a type attribute.

Flux creates one or more nested <forward> elements of the following syntax:

<forward name="<GuardCondition>" path="<Path>">

If such a <forward> element is created for the first time, i. e. it does not yet exist under the same name in the old version of the struts-config-<module>.xml, then Flux sets the name and the path attribute. If, however, it already existed before Flux preserves all old attributes and nested elements unchanged. The old path attribute, however, must be a true extension of the newly generated path attribute in order to be preserved. Otherwise the old path attribute will be ignored, because it might contradict the current model.

See the edit rules to check what and how you may or may not edit in this type of generated action mapping.

Module Activity Mappings

For each entered module Flux generates one action mapping to enter the module and one mapping to continue after return from the exiting module.

The syntax is as follows:

<action path="/Module.<Name>.enter" ...>
<action path="/Module.<Name>.exit" ...>

See the edit rules to check what and how you may or may not edit in this type of generated action mapping.

Page Preprocessing Mappings

Page preprocessing mappings are optional <action> elements that execute a preparatory action before a logical page is mapped, i. e. forwarded to a physical page (usually a JSP).

For each UML page state Flux generates a Struts <action> element of the following syntax if the Flux preference 'Generate page preprocessings' is checked and not overridden by the equally named Flux property of the respective struts-config file:

<action path="/Page.<Name>.display" ...>

If such an <action> element is created for the first time, i. e. it does not yet exist under the same path in the old version of the struts-config-<module>.xml, then Flux adds a default type attribute.

See the edit rules to check what and how you may or may not edit in this type of generated action mapping.

Page State Mappings

Page state mappings are <action> elements that determine how a logical page is mapped, i. e. forwarded to a physical page (usually a JSP).

For each UML page state Flux generates a Struts <action> element of the following syntax:

<action path="/Page.<Name>.doDisplay" ...>

If such an <action> element is created for the first time, i. e. it does not yet exist under the same path in the old version of the struts-config-<module>.xml, then Flux adds a default forward attribute. If, however, it already existed before Flux preserves all old allowable attributes and nested elements unchanged. The attributes 'type', 'include' and 'input' are not allowable because Flux enforces a forward attribute.

See the edit rules to check what and how you may or may not edit in this type of generated action mapping.

If you make use of the optional page mode variable feature one more level of indirection will be generated. This additional dispatcher indirection will transform the internally used logical page name to the externally used name, which is a concatenation of the internally used name and the current value of the mode variable.

Example:

<!--Page States-->
<action path="/Page.Balance.doDisplay" type="de.matthias_burbach.strux.DispatcherAction" parameter="mode">
  <forward name="Demo" path="/Page.BalanceDemo.doDisplay.do" />
  <forward name="Test" path="/Page.BalanceTest.doDisplay.do" />
  <forward name="Real" path="/Page.BalanceReal.doDisplay.do" />
</action>

A forward to display the logical page 'Balance' will first go through one of the above mappings before reaching the actual logical to physical mapping appropriate for the current mode..

<action path="/Page.BalanceDemo.doDisplay" forward="/${locale}/BalanceDemo.jsp" />
<action path="/Page.BalanceTest.doDisplay" forward="/${locale}/BalanceTest.jsp" />
<action path="/Page.BalanceReal.doDisplay" forward="/${locale}/BalanceReal.jsp" />

Final State Mapping

The one final state mapping occurs when the model contains a UML final state. It maps the path '/FinalState' to a type that is executed if any of the other action mappings of the module forwards to it to mark the end of this module's processing chain in the current workflow.

See the edit rules to check what and how you may or may not edit in this type of generated action mapping.

Non-modelled Mappings

If the precaution feature 'Preserve non-modelled action mappings' is switched on (which is the case by default) and there are mappings whose path attribute can not be (re-)generated from the model they are not deleted but moved to the section 'Non-modelled Action Mappings'. If they don't exist for a special reason or if they occur because of a problem in the model which can be fixed they should normally be manually deleted to keep the file tidy.

Action mappings that go in this section can be changed in any way, but note that they are not protected from Flux because of their position in the file under the comment 'Non-modelled Action Mappings' but because of their path that does not match any generated path. So if you want to use non-modelled action mappings for things you cannot do with modelled mappings make sure you use a path that is never generated (e. g. by using a path prefix other than '/Page.', '/Action.', '/Module.' or '/FinalState.').