Sorry for making few typos while cut and pasting in proposed FormTag
patch/extension. Here's correct code:
/** Process path param if present and use
* params from corresponding ActionMapping
*/
public int doStartTag() throws JspException {
if ((path != null) && (path.length () > 0)) {
setAction (mapping); // use is as form action
// Find ActionMapping pointed by the path
ActionMappings actmaps = (ActionMappings)
pageContext.getAttribute
(Action.MAPPINGS_KEY, PageContext.APPLICATION_SCOPE);
ActionMapping actmap = actmaps.findMapping (getMappingPath
(path));
if (actmap == null)
throw new JspException (messages.getMessage("common.io",
"FormTag: No ActionMapping found for form tag path
value: " + path));
// Override FormTag params with bean type and name extracted
from mapping
setType (actmap.getFormClass ());
setName (actmap.getFormAttribute ());
}
return super.doStartTag ();
}
/**
* Identify and return the action path component (from the path URI)
that
* we will use to select an ActionMapping. If no such
* path can be identified, return <code>null</code>.
*/
protected static String getMappingPath (String uri)
{
String path = new String (uri); // make a copy
// For extension matching, we want to strip the extension (if
any)
int slash = path.lastIndexOf ("/");
int period = path.lastIndexOf (".");
if ((period >= 0) && (period > slash))
path = path.substring (0, period);
// Add a leading "/" if missing
if (slash != 0)
path = "/" + path;
return (path);
}
Thanks,
Alec Bau
P.S. Craig, can we make tag classes non "final" so that extending them
will become possible?
Alec Bau wrote:
> I was wondering if it's mandatory to specify on a FormTag "name" and
> "type" parameters since in most
> cases "action" value is actually ActionMapping path that already
> contains all needed information from "action.xml".
>
> I suggest adding to the FormTag a "path" param that if present
> overrides/compliments "action", "type" and/or "name" params. Other
> solution is to define a new tag such as FormPathTag (i.e.
> <struts:pathform>) derived from current FormTag. In any case this will
> allow in a true MVC fashion to keep most technical non design
> information such as full bean class names and id's in a single place
> and not to replicate them through jsp pages. Also this makes FormTag
> extremely easy to explain and use with a single param such as:
>
> <struts:form path="foo.do"/>
>
> I've attached a patch that for brevity extends FormTag (now impossible
> since FormTag class is "final"). New tag's "path" param overrides
> "action", "type" and "name" params if present. Alternatively it's easy
> to check if any of above params are present and if not override them
> with values form ActionMapping.
>
> Corresponding new tag TLD entry should redefine "name" and "type"
> params as optional (or remove them along with "action" altogether)
> and add an optional (or mandatory if "action" and others are removed)
> "path" param.
>
> public class FormPathTag extends FormTag {
>
> /**
> * An URL which path should match according to ActionServlet rules
>
> * action mapping name from action.xml thus eliminating the need
> to specify
> * form tag bean name and type.
> * Supersedes action, type and name params if specified.
> */
> private String path = null;
>
> public String getPath() {
> return (this.path);
> }
>
> public void setPath(String path) {
> this.path = path;
> }
>
> /** Process path param if present and use
> * params from corresponding ActionMapping
> */
> public int doStartTag() throws JspException {
>
> if ((path == null) || (path.length () < 1)) return;
>
> setAction (mapping); // use is as form action
>
> // Find ActionMapping pointed by the path
> ActionMappings actmaps = (ActionMappings)
> pageContext.getAttribute
> (Action.MAPPINGS_KEY, PageContext.APPLICATION_SCOPE);
> ActionMapping actmap = actmaps.findMapping (getMappingPath
> (path));
> if (actmap == null)
> throw new JspException
> (messages.getMessage("common.io",
> "FormTag: No ActionMapping found for form tag path
> value: " + path));
>
> // Override FormTag params with bean type and name extracted
> from mapping
> setType (actmap.getFormClass ());
> setName (actmap.getFormAttribute ());
>
> super.doStartTag();
> }
>
> /**
> * Identify and return the action path component (from the path
> URI) that
> * we will use to select an ActionMapping. If no such
> * path can be identified, return <code>null</code>.
> */
> protected static String getMappingPath (String uri)
> {
> String path = new String (uri); // make a copy
>
> // For extension matching, we want to strip the extension (if
> any)
> int slash = path.lastIndexOf ("/");
> int period = path.lastIndexOf (".");
> if ((period >= 0) && (period > slash))
> path = path.substring (0, period);
>
> // Add a leading "/" if missing
> if (!path.startsWith ("/"))
> path = "/" + path;
>
> return (path);
> }
>
> public void release() {
> super.release();
> path = null;
> }
>
> }
>
|