View Javadoc
1   package com.randomnoun.common.webapp.taglib;
2   
3   /* (c) 2013 randomnoun. All Rights Reserved. This work is licensed under a
4    * BSD Simplified License. (http://www.randomnoun.com/bsd-simplified.html)
5    */
6   import java.util.HashMap;
7   import java.util.Iterator;
8   import java.util.Map;
9   
10  import jakarta.servlet.jsp.JspException;
11  import jakarta.servlet.jsp.tagext.TagSupport;
12  
13  /**
14   * This is an abstract taglib, which can be used to propagate standard HTML attributes
15   * through to a HTML page. It provides handlers for all the 'general' attributes
16   * that are present for most HTML tags (e.g. onclick, style, ...).
17   *
18   * <p>Other taglibs that are used to generate HTML elements (e.g. SelectTag), can
19   * extend this class to take advantage of this functionality.
20   *
21   * <p>Superclasses may override any method defined in this tag to provide their own
22   * special handling.
23   *
24   * <b>The attributes handled by this tag</b> are
25        accesskey, styleClass, contenteditable, dir, disabled, lang, language, maxlength,
26        size, style, title, width, onactivate, onafterupdate, onbeforeactvate,
27        onbeforecut, onbeforedeactivate, onbeforeeditfocus, onbeforepaste,
28        onbeforeupdate, onblur, onchange, onclick, oncontextmenu, oncontrolselect,
29        oncut, ondblclick, ondeactivate, ondrag, ondragend, ondragenter, ondragleave,
30        ondragover, ondragstart, ondrop, onerrorupdate, onfilterchange, onfocus,
31        onfocusin, onfocusout, onhelp, onkeydown, onkeypress, onkeyup, onlosecapture,
32        onmousedown, onmouseenter, onmouseleave, onmousemove, onmouseout, onmouseover,
33        onmouseup, onmousewheel, onmove, onmoveend, onmovestart, onpaste,
34        onpropertychange, onreadystatechange, onresize, onresizeend, onresizestart,
35        onselect, onselectstart, ontimeerror, hidefocus, readonly, tabindex and
36        unselectable.
37   *
38   * <p>Note that the HTML attribute 'class' is now called 'styleClass', since the
39   * Object.getClass() method interferes with standard JavaBean reflection.
40   *
41   * <p>All attributes are lower-case, except extraAttributes (see below).
42   *
43   * <p>Note that the attributes 'name', 'type' and 'value' are intentionally not on this list,
44   * as they would normally be generated by the specific tag libary itself.
45   * 
46   * <p>The 'disabled' attributes has some special handling -- if it's set to the value 
47   * "false", then the attribute is removed. This is due to IE treating 'disabled="false"' as
48   * actually disabling the control. Which is odd.
49   *
50   * <p>The IE-only attributes hidefocus, readonly, tabindex and unselectable are included
51   * on this list, because they seem reasonably useful. The IE-only attributes
52   * begin, end, datafld, datasrc, autocomplete, syncmasterm, timecontainer and vcard_name
53   * are not on this list, because they don't seem as useful. You can always add them if
54   * you think they're needed.
55   *
56   * <p>Values are EL-evaluated (so you can have JSTL-style <code>${xxxx}</code> values).
57   *
58   * <p>Additional attributes can be expressed using the extraAttributes attribute, e.g.
59   * to put a non-standard attribute 'onmousewheelclick' into the element, you could
60   * use, for example:
61   * <pre style="code">
62   * &lt;mm:something extraAttribute="onmousewheelclick='doSomethingInJavascript()'" /&gt;
63   * </pre>
64   *
65   * <p>Any tag that extends this class should have the following text in it's .tld descriptor:
66   * <pre style="code">
67      &lt;!-- Attributes understood by StandardHtmlTag --&gt;
68      &lt;attribute&gt;&lt;name&gt;accesskey&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
69      &lt;attribute&gt;&lt;name&gt;styleClass&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
70      &lt;attribute&gt;&lt;name&gt;contenteditable&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
71      &lt;attribute&gt;&lt;name&gt;dir&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
72      &lt;attribute&gt;&lt;name&gt;disabled&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
73      &lt;attribute&gt;&lt;name&gt;lang&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
74      &lt;attribute&gt;&lt;name&gt;language&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
75      &lt;attribute&gt;&lt;name&gt;maxlength&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
76      &lt;attribute&gt;&lt;name&gt;size&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
77      &lt;attribute&gt;&lt;name&gt;style&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
78      &lt;attribute&gt;&lt;name&gt;title&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
79      &lt;attribute&gt;&lt;name&gt;width&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
80      &lt;attribute&gt;&lt;name&gt;onactivate&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
81      &lt;attribute&gt;&lt;name&gt;onafterupdate&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
82      &lt;attribute&gt;&lt;name&gt;onbeforeactvate&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
83      &lt;attribute&gt;&lt;name&gt;onbeforecut&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
84      &lt;attribute&gt;&lt;name&gt;onbeforedeactivate&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
85      &lt;attribute&gt;&lt;name&gt;onbeforeeditfocus&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
86      &lt;attribute&gt;&lt;name&gt;onbeforepaste&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
87      &lt;attribute&gt;&lt;name&gt;onbeforeupdate&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
88      &lt;attribute&gt;&lt;name&gt;onblur&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
89      &lt;attribute&gt;&lt;name&gt;onchange&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
90      &lt;attribute&gt;&lt;name&gt;onclick&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
91      &lt;attribute&gt;&lt;name&gt;oncontextmenu&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
92      &lt;attribute&gt;&lt;name&gt;oncontrolselect&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
93      &lt;attribute&gt;&lt;name&gt;oncut&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
94      &lt;attribute&gt;&lt;name&gt;ondblclick&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
95      &lt;attribute&gt;&lt;name&gt;ondeactivate&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
96      &lt;attribute&gt;&lt;name&gt;ondrag&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
97      &lt;attribute&gt;&lt;name&gt;ondragend&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
98      &lt;attribute&gt;&lt;name&gt;ondragenter&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
99      &lt;attribute&gt;&lt;name&gt;ondragleave&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
100     &lt;attribute&gt;&lt;name&gt;ondragover&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
101     &lt;attribute&gt;&lt;name&gt;ondragstart&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
102     &lt;attribute&gt;&lt;name&gt;ondrop&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
103     &lt;attribute&gt;&lt;name&gt;onerrorupdate&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
104     &lt;attribute&gt;&lt;name&gt;onfilterchange&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
105     &lt;attribute&gt;&lt;name&gt;onfocus&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
106     &lt;attribute&gt;&lt;name&gt;onfocusin&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
107     &lt;attribute&gt;&lt;name&gt;onfocusout&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
108     &lt;attribute&gt;&lt;name&gt;onhelp&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
109     &lt;attribute&gt;&lt;name&gt;onkeydown&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
110     &lt;attribute&gt;&lt;name&gt;onkeypress&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
111     &lt;attribute&gt;&lt;name&gt;onkeyup&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
112     &lt;attribute&gt;&lt;name&gt;onlosecapture&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
113     &lt;attribute&gt;&lt;name&gt;onmousedown&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
114     &lt;attribute&gt;&lt;name&gt;onmouseenter&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
115     &lt;attribute&gt;&lt;name&gt;onmouseleave&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
116     &lt;attribute&gt;&lt;name&gt;onmousemove&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
117     &lt;attribute&gt;&lt;name&gt;onmouseout&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
118     &lt;attribute&gt;&lt;name&gt;onmouseover&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
119     &lt;attribute&gt;&lt;name&gt;onmouseup&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
120     &lt;attribute&gt;&lt;name&gt;onmousewheel&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
121     &lt;attribute&gt;&lt;name&gt;onmove&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
122     &lt;attribute&gt;&lt;name&gt;onmoveend&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
123     &lt;attribute&gt;&lt;name&gt;onmovestart&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
124     &lt;attribute&gt;&lt;name&gt;onpaste&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
125     &lt;attribute&gt;&lt;name&gt;onpropertychange&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
126     &lt;attribute&gt;&lt;name&gt;onreadystatechange&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
127     &lt;attribute&gt;&lt;name&gt;onresize&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
128     &lt;attribute&gt;&lt;name&gt;onresizeend&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
129     &lt;attribute&gt;&lt;name&gt;onresizestart&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
130     &lt;attribute&gt;&lt;name&gt;onselect&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
131     &lt;attribute&gt;&lt;name&gt;onselectstart&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
132     &lt;attribute&gt;&lt;name&gt;ontimeerror&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
133     &lt;attribute&gt;&lt;name&gt;hidefocus&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
134     &lt;attribute&gt;&lt;name&gt;readonly&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
135     &lt;attribute&gt;&lt;name&gt;tabindex&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
136     &lt;attribute&gt;&lt;name&gt;unselectable&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
137     &lt;attribute&gt;&lt;name&gt;extraAttributes&lt;/name&gt;&lt;required&gt;false&lt;/required&gt;&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;&lt;/attribute&gt;
138  * </pre>
139  *
140  * NB: Implementing classes MUST call getAttributes().clear(); in their doEnd() method,
141  * in case the JSP container decides to reuse taglib instances.
142  *
143  * @author  knoxg
144  * 
145  *
146  */
147 
148 /* that text snippet again without &lt's :
149    <!-- Attributes understood by com.randomnoun.common.webapp.taglib.StandardHtmlTag. -->
150    <attribute><name>accesskey</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
151    <attribute><name>styleClass</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
152    <attribute><name>contenteditable</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
153    <attribute><name>dir</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
154    <attribute><name>disabled</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
155    <attribute><name>lang</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
156    <attribute><name>language</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
157    <attribute><name>maxlength</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
158    <attribute><name>size</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
159    <attribute><name>style</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
160    <attribute><name>title</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
161    <attribute><name>width</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
162    <attribute><name>onactivate</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
163    <attribute><name>onafterupdate</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
164    <attribute><name>onbeforeactvate</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
165    <attribute><name>onbeforecut</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
166    <attribute><name>onbeforedeactivate</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
167    <attribute><name>onbeforeeditfocus</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
168    <attribute><name>onbeforepaste</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
169    <attribute><name>onbeforeupdate</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
170    <attribute><name>onblur</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
171    <attribute><name>onchange</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
172    <attribute><name>onclick</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
173    <attribute><name>oncontextmenu</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
174    <attribute><name>oncontrolselect</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
175    <attribute><name>oncut</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
176    <attribute><name>ondblclick</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
177    <attribute><name>ondeactivate</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
178    <attribute><name>ondrag</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
179    <attribute><name>ondragend</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
180    <attribute><name>ondragenter</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
181    <attribute><name>ondragleave</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
182    <attribute><name>ondragover</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
183    <attribute><name>ondragstart</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
184    <attribute><name>ondrop</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
185    <attribute><name>onerrorupdate</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
186    <attribute><name>onfilterchange</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
187    <attribute><name>onfocus</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
188    <attribute><name>onfocusin</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
189    <attribute><name>onfocusout</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
190    <attribute><name>onhelp</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
191    <attribute><name>onkeydown</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
192    <attribute><name>onkeypress</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
193    <attribute><name>onkeyup</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
194    <attribute><name>onlosecapture</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
195    <attribute><name>onmousedown</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
196    <attribute><name>onmouseenter</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
197    <attribute><name>onmouseleave</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
198    <attribute><name>onmousemove</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
199    <attribute><name>onmouseout</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
200    <attribute><name>onmouseover</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
201    <attribute><name>onmouseup</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
202    <attribute><name>onmousewheel</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
203    <attribute><name>onmove</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
204    <attribute><name>onmoveend</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
205    <attribute><name>onmovestart</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
206    <attribute><name>onpaste</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
207    <attribute><name>onpropertychange</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
208    <attribute><name>onreadystatechange</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
209    <attribute><name>onresize</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
210    <attribute><name>onresizeend</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
211    <attribute><name>onresizestart</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
212    <attribute><name>onselect</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
213    <attribute><name>onselectstart</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
214    <attribute><name>ontimeerror</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
215    <attribute><name>hidefocus</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
216    <attribute><name>readonly</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
217    <attribute><name>tabindex</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
218    <attribute><name>unselectable</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
219    <attribute><name>extraAttributes</name><required>false</required><rtexprvalue>true</rtexprvalue></attribute>
220  */
221 @SuppressWarnings("serial")
222 public abstract class StandardHtmlTag
223     extends TagSupport {
224     
225     
226     protected Map<String, String> attributes = new HashMap<String, String>();
227     protected String extraAttributes = null;
228 
229     public void setAccessKey(String accessKey) { attributes.put("accessKey", accessKey); }
230     public void setStyleClass(String clazz) { attributes.put("class", clazz); }   
231     public void setContenteditable(String contentEditable) { attributes.put("contenteditable", contentEditable); }   
232     public void setDir(String dir) { attributes.put("dir", dir); }   
233     public void setDisabled(String disabled) { attributes.put("disabled", disabled); }   
234     public void setLang(String lang) { attributes.put("lang", lang); }   
235     public void setLanguage(String language) { attributes.put("language", language); }   
236     public void setMaxlength(String maxLength) { attributes.put("maxlength", maxLength); }   
237     public void setSize(String size) { attributes.put("size", size); }   
238     public void setStyle(String style) { attributes.put("style", style); }   
239     public void setTitle(String title) { attributes.put("title", title); }   
240     public void setWidth(String width) { attributes.put("width", width); }   
241     public void setOnactivate(String onactivate) { attributes.put("onactivate", onactivate); }   
242     public void setOnafterupdate(String onafterupdate) { attributes.put("onafterupdate", onafterupdate); }   
243     public void setOnbeforeactvate(String onbeforeactvate) { attributes.put("onbeforeactvate", onbeforeactvate); }   
244     public void setOnbeforecut(String onbeforecut) { attributes.put("onbeforecut", onbeforecut); }   
245     public void setOnbeforedeactivate(String onbeforedeactivate) { attributes.put("onbeforedeactivate", onbeforedeactivate); }   
246     public void setOnbeforeeditfocus(String onbeforeeditfocus) { attributes.put("onbeforeeditfocus", onbeforeeditfocus); }   
247     public void setOnbeforepaste(String onbeforepaste) { attributes.put("onbeforepaste", onbeforepaste); }   
248     public void setOnbeforeupdate(String onbeforeupdate) { attributes.put("onbeforeupdate", onbeforeupdate); }   
249     public void setOnblur(String onblur) { attributes.put("onblur", onblur); }   
250     public void setOnchange(String onchange) { attributes.put("onchange", onchange); }   
251     public void setOnclick(String onclick) { attributes.put("onclick", onclick); }   
252     public void setOncontextmenu(String oncontextmenu) { attributes.put("oncontextmenu", oncontextmenu); }   
253     public void setOncontrolselect(String oncontrolselect) { attributes.put("oncontrolselect", oncontrolselect); }   
254     public void setOncut(String oncut) { attributes.put("oncut", oncut); }   
255     public void setOndblclick(String ondblclick) { attributes.put("ondblclick", ondblclick); }   
256     public void setOndeactivate(String ondeactivate) { attributes.put("ondeactivate", ondeactivate); }   
257     public void setOndrag(String ondrag) { attributes.put("ondrag", ondrag); }   
258     public void setOndragend(String ondragend) { attributes.put("ondragend", ondragend); }   
259     public void setOndragenter(String ondragenter) { attributes.put("ondragenter", ondragenter); }   
260     public void setOndragleave(String ondragleave) { attributes.put("ondragleave", ondragleave); }   
261     public void setOndragover(String ondragover) { attributes.put("ondragover", ondragover); }   
262     public void setOndragstart(String ondragstart) { attributes.put("ondragstart", ondragstart); }   
263     public void setOndrop(String ondrop) { attributes.put("ondrop", ondrop); }   
264     public void setOnerrorupdate(String onerrorupdate) { attributes.put("onerrorupdate", onerrorupdate); }   
265     public void setOnfilterchange(String onfilterchange) { attributes.put("onfilterchange", onfilterchange); }   
266     public void setOnfocus(String onfocus) { attributes.put("onfocus", onfocus); }   
267     public void setOnfocusin(String onfocusin) { attributes.put("onfocusin", onfocusin); }   
268     public void setOnfocusout(String onfocusout) { attributes.put("onfocusout", onfocusout); }   
269     public void setOnhelp(String onhelp) { attributes.put("onhelp", onhelp); }   
270     public void setOnkeydown(String onkeydown) { attributes.put("onkeydown", onkeydown); }   
271     public void setOnkeypress(String onkeypress) { attributes.put("onkeypress", onkeypress); }   
272     public void setOnkeyup(String onkeyup) { attributes.put("onkeyup", onkeyup); }   
273     public void setOnlosecapture(String onlosecapture) { attributes.put("onlosecapture", onlosecapture); }   
274     public void setOnmousedown(String onmousedown) { attributes.put("onmousedown", onmousedown); }   
275     public void setOnmouseenter(String onmouseenter) { attributes.put("onmouseenter", onmouseenter); }   
276     public void setOnmouseleave(String onmouseleave) { attributes.put("onmouseleave", onmouseleave); }   
277     public void setOnmousemove(String onmousemove) { attributes.put("onmousemove", onmousemove); }   
278     public void setOnmouseout(String onmouseout) { attributes.put("onmouseout", onmouseout); }   
279     public void setOnmouseover(String onmouseover) { attributes.put("onmouseover", onmouseover); }   
280     public void setOnmouseup(String onmouseup) { attributes.put("onmouseup", onmouseup); }   
281     public void setOnmousewheel(String onmousewheel) { attributes.put("onmousewheel", onmousewheel); }   
282     public void setOnmove(String onmove) { attributes.put("onmove", onmove); }   
283     public void setOnmoveend(String onmoveend) { attributes.put("onmoveend", onmoveend); }   
284     public void setOnmovestart(String onmovestart) { attributes.put("onmovestart", onmovestart); }   
285     public void setOnpaste(String onpaste) { attributes.put("onpaste", onpaste); }   
286     public void setOnpropertychange(String onpropertychange) { attributes.put("onpropertychange", onpropertychange); }   
287     public void setOnreadystatechange(String onreadystatechange) { attributes.put("onreadystatechange", onreadystatechange); }   
288     public void setOnresize(String onresize) { attributes.put("onresize", onresize); }   
289     public void setOnresizeend(String onresizeend) { attributes.put("onresizeend", onresizeend); }   
290     public void setOnresizestart(String onresizestart) { attributes.put("onresizestart", onresizestart); }   
291     public void setOnselect(String onselect) { attributes.put("onselect", onselect); }   
292     public void setOnselectstart(String onselectstart) { attributes.put("onselectstart", onselectstart); }   
293     public void setOntimeerror(String ontimeerror) { attributes.put("ontimeerror", ontimeerror); }   
294     public void setHidefocus(String hideFocus) { attributes.put("hidefocus", hideFocus); }   
295     public void setReadonly(String readOnly) { attributes.put("readonly", readOnly); }   
296     public void setTabindex(String tabIndex) { attributes.put("tabindex", tabIndex); }   
297     public void setUnselectable(String unselectable) { attributes.put("unselectable", unselectable); }   
298     public void setExtraAttributes(String extraAttributes) { this.extraAttributes = extraAttributes; }   
299     
300     protected Map<String, String> getAttributes() { return attributes; }   
301     protected String getExtraAttributes() { return extraAttributes; } 
302 
303     /** Allow JSTL EL expressions within all attributes.
304      *
305      * @throws JspException An exception occurred evaluating the EL.
306      */
307     protected void evaluateAttributes()
308         throws JspException {
309         // assume the tag is the tag Class name, with the final 'Tag' removed, e.g.
310         //    com.randomnoun.common.webapp.taglib.SelectTag
311         // implements the custom tag
312         //    select
313         String tagName = this.getClass().getName();
314 
315         tagName = tagName.substring(tagName.lastIndexOf('.') + 1);
316         tagName = tagName.toLowerCase();
317 
318         if (tagName.endsWith("Tag")) {
319             tagName = tagName.substring(0, tagName.length() - 3);
320         }
321 
322         /*
323         try {
324             Object object = ExpressionUtil.evalNotNull(
325               tagName, "extraAttributes", extraAttributes, Object.class, this, pageContext);
326 
327             // how can this ever return null !?
328             if (object != null) {
329                 extraAttributes = object.toString();
330             }
331         } catch (NullAttributeException ex) {
332             // ignore
333         }
334         
335         for (Iterator<String> i = attributes.keySet().iterator(); i.hasNext();) {
336             String key = (String) i.next();
337             String value = (String) attributes.get(key);
338 
339             try {
340                 value = ExpressionUtil.evalNotNull( 
341                   tagName, key, value, Object.class, this, pageContext).toString();
342                 attributes.put(key, value);
343             } catch (NullAttributeException ex) {
344                 // ignore
345             }
346         }
347         */
348 
349         if ("false".equals(attributes.get("disabled"))) {
350             attributes.remove("disabled");
351         }
352 
353     }
354 
355     /** Returns a string with contains all attributes assigned to this tag, in key="value"
356      * format.
357      * 
358      * <p>(NB: values are not currently quote-escaped here) 
359      *
360      * @return All attributes assigned to this tag.
361      */
362     protected String getAttributeString() {
363         StringBuffer sb = new StringBuffer();
364         for (Iterator<Map.Entry<String, String>> i = attributes.entrySet().iterator(); i.hasNext();) {
365             Map.Entry<String, String> entry = i.next();
366             sb.append(entry.getKey() + "=\"" + entry.getValue() + "\" ");
367         }
368         return sb.toString() + (extraAttributes == null ? "" : extraAttributes);
369     }
370 
371     /** Call this function in your tag's doEnd() method, to clear all stored attributes
372      *  from this tag. */
373     protected void clearAttributes() {
374         this.extraAttributes = null;
375         attributes.clear();
376     }
377 }