You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by bu...@apache.org on 2005/01/12 14:38:10 UTC

DO NOT REPLY [Bug 33064] New: - Struts tags must check attribute values using isEmpty(), not against nulls

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=33064>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=33064

           Summary: Struts tags must check attribute values using isEmpty(),
                    not against nulls
           Product: Struts
           Version: 1.2.6 Beta
          Platform: PC
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Custom Tags
        AssignedTo: dev@struts.apache.org
        ReportedBy: vspa@mail.ru


There is an architectural problem with Struts tags used in tag files.

As you know, in every Struts tag decision on whether attribute has a value set
is based on comparison to null. Example: 
        if (accesskey != null) {
            results.append(" accesskey=\"");
            results.append(accesskey);
            results.append("\"");
        }
Where "accesskey" is an attribute of html:select tag.

The following example shows why usage of Struts tags is substantially restricted
in tag files because of that feature.

The following "icon" tag renders a hyperlink based on "type" attribute (say,
"remove" or "add"), displaying corresponding icon. It has 2 mutually exclusive
attributes: "action" and "href" and one optional attribute "onclick".

=== icon.tagx begins ===

<?xml version="1.0" encoding="UTF-8"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:html="http://struts.apache.org/tags-html" version="2.0" >
  <jsp:directive.tag body-content="empty"/>
  <jsp:directive.attribute name="type" required="true" rtexprvalue="true" />
  <jsp:directive.attribute name="action" required="false" rtexprvalue="true" />
  <jsp:directive.attribute name="href" required="false" rtexprvalue="true" />
  <jsp:directive.attribute name="onclick" required="false" rtexprvalue="true" />

  <html:link action="${action}">
      <html:img page="images/${type}.gif" border="0"/>
  </html:link>

</jsp:root>

=== icon.tagx ends ===

Question here is how should we invoke html:link tag based on value of the
attributes? Ok, we could use <c:choose> like:

<c:choose>
  <c:if test="${not empty action}">
    <!-- use value of action atribute -->
    <html:link action="${action}">
       <html:img page="images/${type}.gif" border="0"/>
    </html:link>
  </c:if>
  <c:otherwise>
    <!-- use value of href atribute -->
    <html:link href="${href}">
       <html:img page="images/${type}.gif" border="0"/>
    </html:link>
  </c:otherwise>
</c:choose>

this would be correct if we had only "action" and "href", but we also have
"onclick". That means, that in every if/otherwise section we need to add same
check for presence of "onclick" attribute. If we had not 3 but 10 attributes,
then total number of <if> statements would be 2^9 which is far beyond reasonable
limits.

The most obvious and conscious solution would be to use the following
construction instead:

  <html:link action="${action}" href="${href}" onclick="${onclick}">
      <html:img page="images/${type}.gif" border="0"/>
  </html:link>

So if icon tag is invoked via <my:icon action="/Action" type="add"/> then "href"
and "onclick" attributes would be nulls and, say, href="${href}" will not change
the default value (null) of the html:link "href" property (call setHref(null);
on tag handler). But this is not true because EL evaluates nulls into empty
strings, so what happens is that html:link tag receives empty (not null) "href"
and "onclick" properties which produces an error message (setHref(""); on tag
handler).

The solution would be to make Struts to check attributes for emptiness (like
StringUtils.isEmpty(), i.e. == null or ""), not just for nulls. Then it would work.

Example:
        if (StringUtils.isNotEmpty(accesskey)) {
            results.append(" accesskey=\"");
            results.append(accesskey);
            results.append("\"");
        }
Where StringUtils is from jakarta commons lang package.

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org