KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > tags > html > HtmlBaseTag


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Header:$
17  */

18 package org.apache.beehive.netui.tags.html;
19
20 import org.apache.beehive.netui.tags.AbstractClassicTag;
21 import org.apache.beehive.netui.tags.IAttributeConsumer;
22 import org.apache.beehive.netui.tags.IHtmlAttrs;
23 import org.apache.beehive.netui.tags.TagConfig;
24 import org.apache.beehive.netui.tags.javascript.ScriptRequestState;
25 import org.apache.beehive.netui.tags.rendering.AbstractHtmlControlState;
26 import org.apache.beehive.netui.tags.rendering.AbstractHtmlState;
27 import org.apache.beehive.netui.util.Bundle;
28
29 import javax.servlet.http.HttpServletRequest JavaDoc;
30 import javax.servlet.jsp.JspException JavaDoc;
31 import javax.servlet.jsp.tagext.Tag JavaDoc;
32
33 /**
34  * [Base] Anchor, Form, Image, ImageAnchor (Image), Label, SelectOption
35  * [FocusBase] Button, CheckBoxOption, ImageButton, RadioButtonOption
36  * [DataSource] FileUpload
37  * [DefaultableDatSource] CheckBox, TextArea, TextBox
38  * [OptionsDataSource] Select
39  * [GroupDataSource] CheckBoxGroup, RadioButtonGroup
40  */

41 abstract public class HtmlBaseTag extends AbstractClassicTag
42         implements HtmlConstants, IAttributeConsumer, IHtmlAttrs
43 {
44
45     /**
46      * This method will return the state associated with the tag. This is used by this
47      * base class to access the individual state objects created by the tags.
48      * @return a subclass of the <code>AbstractHtmlState</code> class.
49      */

50     abstract protected AbstractHtmlState getState();
51
52     //***************************** The IHtmlCore properties *********************************/
53

54     /**
55      * Sets the style of the rendered html tag.
56      * @param style the html style.
57      * @jsptagref.attributedescription Specifies style information for the current element.
58      * @jsptagref.databindable false
59      * @jsptagref.attributesyntaxvalue <i>string_style</i>
60      * @netui:attribute required="false" rtexprvalue="true"
61      * description="Specifies style information for the current element."
62      */

63     public void setStyle(String JavaDoc style)
64     {
65         if ("".equals(style))
66             return;
67         AbstractHtmlState tsh = getState();
68         tsh.style = style;
69     }
70
71     /**
72      * Sets the style class of the rendered html tag.
73      * @param styleClass the html style class.
74      * @jsptagref.attributedescription The style class (a style sheet selector).
75      * @jsptagref.databindable false
76      * @jsptagref.attributesyntaxvalue <i>string_styleClass</i>
77      * @netui:attribute required="false" rtexprvalue="true"
78      * description="The style class (a style sheet selector)."
79      */

80     public void setStyleClass(String JavaDoc styleClass)
81     {
82         if ("".equals(styleClass))
83             return;
84         AbstractHtmlState tsh = getState();
85         tsh.styleClass = styleClass;
86     }
87
88     /**
89      * Set the ID of the tag.
90      * @param tagId the tagId. A value is required.
91      * @jsptagref.attributedescription <p>String value. Sets the <code>id</code> (or <code>name</code>) attribute of the rendered HTML tag.
92      * Note that the real id attribute rendered in the browser may be
93      * changed by the application container (for example, Portal containers may change
94      * the rendered id value to ensure the uniqueness of
95      * id's on the page). In this case, the real id rendered
96      * in the browser may be looked up
97      * through the JavaScript function <code>lookupIdByTagId( tagId, tag )</code>.
98      *
99      * <p>For example, assume that some tag's <code>tagId</code> attribute is set to <code>foo</code>.
100      *
101      * <pre> &lt;netui:textBox <b>tagId="foo"</b> /></pre>
102      *
103      * <p>Then the following JavaScript function will return the real id attribute rendered in the browser:
104      *
105      * <pre> lookupIdByTagId( "foo", this )</pre>
106      *
107      * <p>To get a &lt;netui:form> element and all of its children elements in JavaScript, use
108      * the same JavaScript function <code>lookupIdByTagId( tagId, tag )</code>. For example,
109      * assume that there is a &lt;netui:form> whose
110      * tagId attribute is set to <code>bar</code>.
111      *
112      * <pre> &lt;netui:form <b>tagId="bar"</b> ></pre>
113      *
114      * <p>Then the following JavaScript function will return the &lt;netui:form> element
115      * and its children (packaged as an array).
116      *
117      * <pre> document[lookupIdByTagId( "bar", this )]</pre>
118      *
119      * <p>To retreive the value entered into a &lt;netui:textBox> within the &lt;netui:form> tag, use the following
120      * JavaScript expression.
121      *
122      * <pre> document[lookupIdByTagId("bar", this)][lookupIdByTagId("foo", this)].value</pre>
123      *
124      * <p>The second parameter ensures that the JavaScript function
125      * begins its search within the correct Portlet scope. Pass the
126      * JavaScript keyword <code>this</code> as the second parameter.
127      * @jsptagref.databindable false
128      * @jsptagref.attributesyntaxvalue <i>string_tagId</i>
129      * @netui:attribute required="false" rtexprvalue="true"
130      * description="String value. Sets the id (or name) attribute of the rendered HTML tag. "
131      */

132     public void setTagId(String JavaDoc tagId)
133             throws JspException JavaDoc
134     {
135         // JSP 2.0 EL will convert a null into a empty string "".
136
// If we get a "" we will display an error.
137
AbstractHtmlState tsh = getState();
138         tsh.id = setRequiredValueAttribute(tagId, "tagId");
139     }
140
141     /**
142      * Return the ID of the tag. The id may be rewritten by the container (such
143      * as a portal) to make sure it is unique. JavaScript my lookup the actual id
144      * of the element by looking it up in the <code>netui_names</code> table written
145      * into the HTML.
146      * @return the tagId.
147      */

148     public String JavaDoc getTagId()
149     {
150         AbstractHtmlState tsh = getState();
151         return tsh.id;
152     }
153
154     /**
155      * Sets the value of the title attribute.
156      * @param title
157      * @jsptagref.attributedescription The title.
158      * @jsptagref.databindable false
159      * @jsptagref.attributesyntaxvalue <i>string_title</i>
160      * @netui:attribute required="false" rtexprvalue="true"
161      * description="The title. "
162      */

163     public void setTitle(String JavaDoc title)
164     {
165         AbstractHtmlState tsh = getState();
166         tsh.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TITLE, title);
167     }
168
169     /******************** the HtmlI18n properties ******************************************/
170     /**
171      * Sets the lang attribute for the HTML element.
172      * @param lang
173      * @jsptagref.attributedescription Sets the language code for the base language of an
174      * element's attribute values and text content.
175      * @jsptagref.databindable false
176      * @jsptagref.attributesyntaxvalue <i>string_lang</i>
177      * @netui:attribute required="false" rtexprvalue="true"
178      * description="Sets the language code for the base language of an element's attribute values and text content."
179      */

180     public void setLang(String JavaDoc lang)
181     {
182         AbstractHtmlState tsh = getState();
183         tsh.registerAttribute(AbstractHtmlState.ATTR_GENERAL, LANG, lang);
184     }
185
186     /**
187      * Sets the dir attribute for the HTML element.
188      * @param dir
189      * @jsptagref.attributedescription Specifies the direction of text. (<code>LTR | RTL</code>)
190      * @jsptagref.databindable false
191      * @jsptagref.attributesyntaxvalue <i>string_dir</i>
192      * @netui:attribute required="false" rtexprvalue="true"
193      * description="Specifies the direction of text. (LTR | RTL)"
194      */

195     public void setDir(String JavaDoc dir)
196     {
197         AbstractHtmlState tsh = getState();
198         tsh.registerAttribute(AbstractHtmlState.ATTR_GENERAL, DIR, dir);
199     }
200
201     //******************* the HtmlEvent Properties ****************************************
202
/**
203      * Gets the onClick javascript event.
204      * @return the onClick event.
205      */

206     public String JavaDoc getOnClick()
207     {
208         AbstractHtmlState tsh = getState();
209         return tsh.getAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONCLICK);
210     }
211
212     /**
213      * Sets the onClick javascript event.
214      * @param onclick the onClick event.
215      * @jsptagref.attributedescription The onClick JavaScript event.
216      * @jsptagref.databindable false
217      * @jsptagref.attributesyntaxvalue <i>string_onClick</i>
218      * @netui:attribute required="false" rtexprvalue="true"
219      * description="The onClick JavaScript event."
220      */

221     public void setOnClick(String JavaDoc onclick)
222     {
223         AbstractHtmlState tsh = getState();
224         tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONCLICK, onclick);
225     }
226
227     /**
228      * Sets the onDblClick javascript event.
229      * @param ondblclick the onDblClick event.
230      * @jsptagref.attributedescription The onDblClick JavaScript event.
231      * @jsptagref.databindable false
232      * @jsptagref.attributesyntaxvalue <i>string_onDblClick</i>
233      * @netui:attribute required="false" rtexprvalue="true"
234      * description="The onDblClick JavaScript event."
235      */

236     public void setOnDblClick(String JavaDoc ondblclick)
237     {
238         AbstractHtmlState tsh = getState();
239         tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONDBLCLICK, ondblclick);
240     }
241
242     /**
243      * Sets the onKeyDown javascript event.
244      * @param onkeydown the onKeyDown event.
245      * @jsptagref.attributedescription The onKeyDown JavaScript event.
246      * @jsptagref.databindable false
247      * @jsptagref.attributesyntaxvalue <i>string_onKeyDown</i>
248      * @netui:attribute required="false" rtexprvalue="true"
249      * description="The onKeyDown JavaScript event."
250      */

251     public void setOnKeyDown(String JavaDoc onkeydown)
252     {
253         AbstractHtmlState tsh = getState();
254         tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONKEYDOWN, onkeydown);
255     }
256
257     /**
258      * Sets the onKeyPress javascript event.
259      * @param onkeypress the onKeyPress event.
260      * @jsptagref.attributedescription The onKeyPress JavaScript event.
261      * @jsptagref.databindable false
262      * @jsptagref.attributesyntaxvalue <i>string_onKeyPress</i>
263      * @netui:attribute required="false" rtexprvalue="true"
264      * description="The onKeyPress JavaScript event."
265      */

266     public void setOnKeyPress(String JavaDoc onkeypress)
267     {
268         AbstractHtmlState tsh = getState();
269         tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONKEYPRESS, onkeypress);
270     }
271
272     /**
273      * Sets the onKeyUp javascript event.
274      * @param onkeyup the onKeyUp event.
275      * @jsptagref.attributedescription The onKeyUp JavaScript event.
276      * @jsptagref.databindable false
277      * @jsptagref.attributesyntaxvalue <i>string_onKeyUp</i>
278      * @netui:attribute required="false" rtexprvalue="true"
279      * description="The onKeyUp JavaScript event."
280      */

281     public void setOnKeyUp(String JavaDoc onkeyup)
282     {
283         AbstractHtmlState tsh = getState();
284         tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONKEYUP, onkeyup);
285     }
286
287     /**
288      * Sets the onMouseDown javascript event.
289      * @param onmousedown the onMouseDown event.
290      * @jsptagref.attributedescription The onMouseDown JavaScript event.
291      * @jsptagref.databindable false
292      * @jsptagref.attributesyntaxvalue <i>string_onMouseDown</i>
293      * @netui:attribute required="false" rtexprvalue="true"
294      * description="The onMouseDown JavaScript event."
295      */

296     public void setOnMouseDown(String JavaDoc onmousedown)
297     {
298         AbstractHtmlState tsh = getState();
299         tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONMOUSEDOWN, onmousedown);
300     }
301
302     /**
303      * Sets the onMouseMove javascript event.
304      * @param onmousemove the onMouseMove event.
305      * @jsptagref.attributedescription The onMouseMove JavaScript event.
306      * @jsptagref.databindable false
307      * @jsptagref.attributesyntaxvalue <i>string_onMouseMove</i>
308      * @netui:attribute required="false" rtexprvalue="true"
309      * description="The onMouseMove JavaScript event."
310      */

311     public void setOnMouseMove(String JavaDoc onmousemove)
312     {
313         AbstractHtmlState tsh = getState();
314         tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONMOUSEMOVE, onmousemove);
315     }
316
317     /**
318      * Sets the onMouseOut javascript event.
319      * @param onmouseout the onMouseOut event.
320      * @jsptagref.attributedescription The onMouseOut JavaScript event.
321      * @jsptagref.databindable false
322      * @jsptagref.attributesyntaxvalue <i>string_onMouseOut</i>
323      * @netui:attribute required="false" rtexprvalue="true"
324      * description="The onMouseOut JavaScript event."
325      */

326     public void setOnMouseOut(String JavaDoc onmouseout)
327     {
328         AbstractHtmlState tsh = getState();
329         tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONMOUSEOUT, onmouseout);
330     }
331
332     /**
333      * Sets the onMouseOver javascript event.
334      * @param onmouseover the onMouseOver event.
335      * @jsptagref.attributedescription The onMouseOver JavaScript event.
336      * @jsptagref.databindable false
337      * @jsptagref.attributesyntaxvalue <i>string_onMouseOver</i>
338      * @netui:attribute required="false" rtexprvalue="true"
339      * description="The onMouseOver JavaScript event."
340      */

341     public void setOnMouseOver(String JavaDoc onmouseover)
342     {
343         AbstractHtmlState tsh = getState();
344         tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONMOUSEOVER, onmouseover);
345     }
346
347     /**
348      * Sets the onMouseUp javascript event.
349      * @param onmouseup the onMouseUp event.
350      * @jsptagref.attributedescription The onMouseUp JavaScript event.
351      * @jsptagref.databindable false
352      * @jsptagref.attributesyntaxvalue <i>string_onMouseUp</i>
353      * @netui:attribute required="false" rtexprvalue="true"
354      * description="The onMouseUp JavaScript event."
355      */

356     public void setOnMouseUp(String JavaDoc onmouseup)
357     {
358         AbstractHtmlState tsh = getState();
359         tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONMOUSEUP, onmouseup);
360     }
361
362
363     //******************* Helper Routines *********************************/
364

365     protected String JavaDoc getJavaScriptAttribute(String JavaDoc name)
366     {
367         AbstractHtmlState tsh = getState();
368         return tsh.getAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, name);
369     }
370
371     /**
372      * Attribute implementation.
373      * @param name
374      * @param value
375      * @param tsh
376      * @throws JspException
377      */

378     protected void setStateAttribute(String JavaDoc name, String JavaDoc value, AbstractHtmlState tsh)
379             throws JspException JavaDoc
380     {
381         boolean error = false;
382
383         // validate the name attribute, in the case of an error simply return.
384
if (name == null || name.length() <= 0) {
385             String JavaDoc s = Bundle.getString("Tags_AttributeNameNotSet");
386             registerTagError(s, null);
387             error = true;
388         }
389
390         // it's not legal to set the id or name attributes this way
391
if (name != null && (name.equals(ID) || name.equals(NAME))) {
392             String JavaDoc s = Bundle.getString("Tags_AttributeMayNotBeSet", new Object JavaDoc[]{name});
393             registerTagError(s, null);
394         }
395         if (error)
396             return;
397
398         // if there is a style or class we will let them override the base
399
if (name.equals(CLASS)) {
400             tsh.styleClass = value;
401             return;
402         }
403         else if (name.equals(STYLE)) {
404             tsh.style = value;
405             return;
406         }
407         tsh.registerAttribute(AbstractHtmlState.ATTR_GENERAL, name, value);
408     }
409
410     /**
411      * Base support for the <code>attribute</code> tag. This requires that the tag buffer their body and
412      * write attribute in the end tag. For the HTML tags it is not legal to set
413      * the <code>id</code> or <code>name</code> attributes. In addition, the base tag does
414      * not allow facets to be set. If the attribute is legal it will be added to the
415      * general expression map stored in the <code>AbstractHtmlState</code> of the tag.
416      * @param name The name of the attribute. This value may not be null or the empty string.
417      * @param value The value of the attribute. This may contain an expression.
418      * @param facet The name of a facet to which the attribute will be applied. This is optional.
419      * @throws JspException A JspException may be thrown if there is an error setting the attribute.
420      */

421     public void setAttribute(String JavaDoc name, String JavaDoc value, String JavaDoc facet)
422             throws JspException JavaDoc
423     {
424         if (facet != null) {
425             String JavaDoc s = Bundle.getString("Tags_AttributeFacetNotSupported", new Object JavaDoc[]{facet});
426             registerTagError(s, null);
427         }
428         AbstractHtmlState tsh = getState();
429         setStateAttribute(name, value, tsh);
430     }
431
432     /**
433      * Returns the closest parent form tag, or null if there is none.
434      */

435     protected Form getNearestForm()
436     {
437         Tag parentTag = getParent();
438         while (parentTag != null) {
439             if (parentTag instanceof Form)
440                 return (Form) parentTag;
441             parentTag = parentTag.getParent();
442         }
443         return null;
444     }
445
446     /**
447      * Assumptions:
448      * <ul>
449      * <li>The state.name must be fully formed or the "real name" of the form.</li>
450      * <li>The state.id is the tagId value set on the tag and <b>has not</b> be rewritten yet to form the "real id"</li>
451      * </ul>
452      * @param state
453      * @param parentForm
454      * @return String
455      */

456     protected final String JavaDoc renderNameAndId(HttpServletRequest JavaDoc request, AbstractHtmlState state, Form parentForm)
457     {
458         // if id is not set then we need to exit
459
if (state.id == null)
460             return null;
461
462         // check to see if this is an instance of a HTML Control
463
boolean ctrlState = (state instanceof AbstractHtmlControlState);
464
465         // form keeps track of this so that it can add this control to it's focus map
466
if (parentForm != null && ctrlState) {
467             AbstractHtmlControlState hcs = (AbstractHtmlControlState) state;
468             if (hcs.name == null && parentForm.isFocusSet())
469                 hcs.name = state.id;
470             parentForm.addTagID(state.id, ((AbstractHtmlControlState) state).name);
471         }
472
473         // rewrite the id, save the original value so it can be used in maps
474
String JavaDoc id = state.id;
475         state.id = getIdForTagId(id);
476
477         // Legacy Java Script support -- This writes out a single table with both the id and names
478
// mixed. This is legacy support to match the pre beehive behavior.
479
String JavaDoc idScript = null;
480         if (TagConfig.isLegacyJavaScript()) {
481             ScriptRequestState srs = ScriptRequestState.getScriptRequestState(request);
482             if (!ctrlState) {
483                 idScript = srs.mapLegacyTagId(getScriptReporter(), id, state.id);
484             }
485             else {
486                 AbstractHtmlControlState cState = (AbstractHtmlControlState) state;
487                 if (cState.name != null)
488                     idScript = srs.mapLegacyTagId(getScriptReporter(), id, cState.name);
489                 else
490                     idScript = srs.mapLegacyTagId(getScriptReporter(), id, state.id);
491             }
492         }
493
494         // map the tagId to the real id
495
String JavaDoc name = null;
496         if (ctrlState) {
497             AbstractHtmlControlState cState = (AbstractHtmlControlState) state;
498             name = cState.name;
499         }
500
501         String JavaDoc script = renderDefaultNameAndId((HttpServletRequest JavaDoc) pageContext.getRequest(), state, id, name);
502         if (script != null) {
503             if (idScript != null) {
504                 idScript = idScript + script;
505             }
506             else {
507                 idScript = script;
508             }
509         }
510         return idScript;
511     }
512
513
514     protected String JavaDoc renderDefaultNameAndId(HttpServletRequest JavaDoc request, AbstractHtmlState state, String JavaDoc id, String JavaDoc name)
515     {
516
517         // map the tagId to the real id
518
String JavaDoc script = null;
519         if (TagConfig.isDefaultJavaScript()) {
520             ScriptRequestState srs = ScriptRequestState.getScriptRequestState(request);
521             script = srs.mapTagId(getScriptReporter(), id, state.id, name);
522         }
523         return script;
524     }
525
526     /**
527      * Free the state variables of this base class.
528      */

529     protected void localRelease()
530     {
531         super.localRelease();
532     }
533
534     /**
535      * This method will take any absolute URL that doesn't contain the scheme part and append
536      * the context path. In other words, if the URL starts with '/' and the context path isn't
537      * present it will be added.
538      * @param url The url to be added.
539      * @return a url with the context path if the url begins with '/' otherwise the unchanged url.
540      */

541     protected String JavaDoc qualifyUrlToContext(String JavaDoc url)
542     {
543         /*
544         // This has been removed because we are not supporting this within the tags. Question: should we?
545         if (url != null && url.length() > 0) {
546             if (url.charAt(0) == '/') {
547                 HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
548                 String ctxtPath = request.getContextPath();
549                 if (!url.startsWith(ctxtPath)) {
550                     url = ctxtPath + url;
551                     return url;
552                 }
553             }
554         }
555         */

556         return url;
557     }
558 }
559
Popular Tags