KickJava   Java API By Example, From Geeks To Geeks.

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


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.pageflow.ProcessPopulate;
21 import org.apache.beehive.netui.pageflow.RequestParameterHandler;
22 import org.apache.beehive.netui.tags.ByRef;
23 import org.apache.beehive.netui.tags.IHtmlAccessable;
24 import org.apache.beehive.netui.tags.naming.FormDataNameInterceptor;
25 import org.apache.beehive.netui.tags.naming.IndexedNameInterceptor;
26 import org.apache.beehive.netui.tags.naming.PrefixNameInterceptor;
27 import org.apache.beehive.netui.tags.rendering.*;
28 import org.apache.beehive.netui.util.Bundle;
29 import org.apache.beehive.netui.util.logging.Logger;
30
31 import javax.servlet.ServletRequest JavaDoc;
32 import javax.servlet.http.HttpServletRequest JavaDoc;
33 import javax.servlet.jsp.JspException JavaDoc;
34 import javax.servlet.jsp.tagext.Tag JavaDoc;
35 import java.util.ArrayList JavaDoc;
36 import java.util.Collections JavaDoc;
37 import java.util.List JavaDoc;
38
39 /**
40  * Generates a checkbox which binds to a form bean property or databound expression.
41  * CheckBox should be used on its own and not within a CheckBoxGroup. CheckBox ignores its
42  * body content.
43  *
44  * CheckBoxes can bind to boolean, Boolean, and Strings.
45  * @jsptagref.tagdescription <p>Generates a single HTML checkbox. The &lt;netui:checkBox> tag should be used on its own, not within a
46  * {@link CheckBoxGroup}.
47  *
48  * <p>The &lt;netui:checkBox> tag can be data bound to a boolean or Boolean type. For instance,
49  * the following &lt;netui:checkBox> tag...
50  *
51  * <pre> &lt;netui:checkBox dataSource="actionForm.checkBoxValue"/></pre>
52  *
53  * ...must be bound to a boolean or Boolean field in the Form Bean...
54  *
55  * <pre> public static class ProcessDataForm extends FormData
56  * {
57  * private boolean checkBoxValue;
58  *
59  * public void setCheckBoxValue(boolean checkBoxValue)
60  * {
61  * this.checkBoxValue = checkBoxValue;
62  * }
63  *
64  * public boolean isCheckBoxValue()
65  * {
66  * return this.checkBoxValue;
67  * }
68  * }</pre>
69  * @example In this sample, the &lt;netui:checkBox reads it initial value from the
70  * Form Bean field <code>wantSpecialOffers</code>. Upon submission, the user specified value is
71  * loaded into the same Form Bean field. The data is submitted to the
72  * action method <code>processData</code>.
73  * <pre> &lt;netui:form action="processData">
74  * Do you want to be notified of special offers?
75  * &lt;netui:checkBox dataSource="actionForm.wantsSpecialOffers"/>&lt;br>
76  * &lt;netui:button value="Submit" type="submit"/>
77  * &lt;/netui:form></pre>
78  * @netui:tag name="checkBox" description="Generates a checkbox that binds to a form bean property or databound expression."
79  */

80 public class CheckBox
81         extends HtmlDefaultableDataSourceTag
82         implements IHtmlAccessable
83 {
84     private static final Logger logger = Logger.getInstance(CheckBox.class);
85
86     private InputBooleanTag.State _state = new InputBooleanTag.State();
87     private InputHiddenTag.State _hiddenState = new InputHiddenTag.State();
88
89     private static final String JavaDoc CHECKBOX_KEY = "checkbox_key";
90     private static final String JavaDoc OLDVALUE_SUFFIX = "OldValue";
91
92     private static final List JavaDoc _internalNamingChain;
93
94     static
95     {
96         List JavaDoc l = new ArrayList JavaDoc(3);
97         l.add(new FormDataNameInterceptor());
98         l.add(new IndexedNameInterceptor());
99         l.add(new PrefixNameInterceptor(CHECKBOX_KEY));
100         _internalNamingChain = Collections.unmodifiableList(l);
101     }
102
103     static
104     {
105         org.apache.beehive.netui.pageflow.ProcessPopulate.registerPrefixHandler(CHECKBOX_KEY, new CheckBoxPrefixHandler());
106     }
107
108     /**
109      * The handler for naming and indexing the CheckBox.
110      */

111     public static class CheckBoxPrefixHandler
112             implements RequestParameterHandler
113     {
114         /**
115          * Determines the current state of the CheckBox (true or false) based on the Request.
116          */

117         public void process(HttpServletRequest JavaDoc request, String JavaDoc key, String JavaDoc expr,
118                             ProcessPopulate.ExpressionUpdateNode node)
119         {
120             String JavaDoc returnVal = null;
121             if (!key.endsWith(OLDVALUE_SUFFIX)) {
122                 //This checkbox is true and should stay that way
123
returnVal = "true";
124             }
125             else {
126                 //Check the request to see if checkBox also exists
127
String JavaDoc newKey = key.substring(0, key.indexOf(OLDVALUE_SUFFIX));
128                 String JavaDoc checkBox = request.getParameter(newKey);
129                 if (checkBox != null) {
130                     returnVal = "true";
131                 }
132                 else {
133                     returnVal = "false";
134                 }
135             }
136
137             if (node.expression.endsWith(OLDVALUE_SUFFIX)) {
138                 node.expression = node.expression.substring(0, node.expression.indexOf(OLDVALUE_SUFFIX));
139
140             }
141
142             node.values = new String JavaDoc[]{returnVal};
143
144             if (logger.isDebugEnabled()) {
145                 logger.debug("*********************************************\n" +
146                         "process with key \"" + key + "\" and expression \"" + node.expression + "\"" + "and result: " + returnVal + "\n" +
147                         "*********************************************\n");
148             }
149         }
150     }
151
152     public CheckBox()
153     {
154         super();
155     }
156
157     /**
158      * Return the name of the Tag.
159      */

160     public String JavaDoc getTagName()
161     {
162         return "CheckBox";
163     }
164
165     /**
166      * Base support for the attribute tag. This is overridden to prevent setting the <code>type</code>,
167      * <code>checked</code> and <code>value</code> attributes.
168      * @param name The name of the attribute. This value may not be null or the empty string.
169      * @param value The value of the attribute. This may contain an expression.
170      * @param facet The name of a facet to which the attribute will be applied. This is optional.
171      * @throws JspException A JspException may be thrown if there is an error setting the attribute.
172      */

173     public void setAttribute(String JavaDoc name, String JavaDoc value, String JavaDoc facet)
174             throws JspException JavaDoc
175     {
176         if (name != null) {
177             if (name.equals(TYPE) || name.equals(VALUE) || name.equals(CHECKED)) {
178                 String JavaDoc s = Bundle.getString("Tags_AttributeMayNotBeSet", new Object JavaDoc[]{name});
179                 registerTagError(s, null);
180             }
181             else {
182                 if (name.equals(DISABLED)) {
183                     _state.disabled = true;
184                     return;
185                 }
186             }
187         }
188
189         super.setAttribute(name, value, facet);
190     }
191
192     /**
193      * This method will return the state associated with the tag. This is used by this
194      * base class to access the individual state objects created by the tags.
195      * @return a subclass of the <code>AbstractHtmlState</code> class.
196      */

197     protected AbstractHtmlState getState()
198     {
199         return _state;
200     }
201
202     /**
203      * Return an <code>ArrayList</code> which represents a chain of <code>INameInterceptor</code>
204      * objects. This method by default returns <code>null</code> and should be overridden
205      * by objects that support naming.
206      * @return an <code>ArrayList</code> that will contain <code>INameInterceptor</code> objects.
207      */

208     protected List JavaDoc getNamingChain()
209     {
210         return _internalNamingChain;
211     }
212
213     /**
214      * @return A boolean value.
215      */

216     private boolean evaluateDefaultValue()
217     {
218         if (_defaultValue instanceof String JavaDoc)
219             return Boolean.valueOf((String JavaDoc) _defaultValue).booleanValue();
220         if (_defaultValue instanceof Boolean JavaDoc)
221             return ((Boolean JavaDoc) _defaultValue).booleanValue();
222         return false;
223     }
224
225     /**
226      * Render the checkbox.
227      * @throws JspException if a JSP exception has occurred
228      */

229     public int doStartTag() throws JspException JavaDoc
230     {
231         // evaluate the body so that we can set the attributes
232
return EVAL_BODY_BUFFERED;
233     }
234
235     /**
236      * Save the body content of the checkbox.
237      * @throws JspException if a JSP exception has occurred
238      */

239     public int doAfterBody() throws JspException JavaDoc
240     {
241         return SKIP_BODY;
242     }
243
244     /**
245      * Render the checkbox.
246      * @throws JspException if a JSP exception has occurred
247      */

248     public int doEndTag() throws JspException JavaDoc
249     {
250         Tag JavaDoc parent = getParent();
251         if (parent instanceof CheckBoxGroup)
252             registerTagError(Bundle.getString("Tags_CheckBoxGroupChildError"), null);
253
254         Object JavaDoc val = evaluateDataSource();
255         if (hasErrors())
256             return reportAndExit(EVAL_PAGE);
257
258         ByRef ref = new ByRef();
259         nameHtmlControl(_state, ref);
260
261         String JavaDoc hiddenParamName = _state.name + OLDVALUE_SUFFIX;
262         ServletRequest JavaDoc req = pageContext.getRequest();
263
264         if (val instanceof String JavaDoc) {
265             if (val != null && Boolean.valueOf(val.toString()).booleanValue())
266                 _state.checked = true;
267             else
268                 _state.checked = false;
269         }
270         else if (val instanceof Boolean JavaDoc) {
271             _state.checked = ((Boolean JavaDoc) val).booleanValue();
272         }
273         else {
274             String JavaDoc oldCheckBoxValue = req.getParameter(hiddenParamName);
275             if (oldCheckBoxValue != null) {
276                 _state.checked = new Boolean JavaDoc(oldCheckBoxValue).booleanValue();
277             }
278             else {
279                 _state.checked = evaluateDefaultValue();
280             }
281         }
282         _state.disabled = isDisabled();
283
284         //Create a hidden field to store the CheckBox oldValue
285
String JavaDoc oldValue = req.getParameter(_state.name);
286         WriteRenderAppender writer = new WriteRenderAppender(pageContext);
287
288         // if the checkbox is disabled we need to not write out the hidden
289
// field because it can cause the default state to change from
290
// true to false. Disabled check boxes do not postback.
291
if (!_state.disabled) {
292             _hiddenState.name = hiddenParamName;
293             if (oldValue == null) {
294                 _hiddenState.value = "false";
295             }
296             else {
297                 _hiddenState.value = oldValue;
298             }
299             TagRenderingBase hiddenTag = TagRenderingBase.Factory.getRendering(TagRenderingBase.INPUT_HIDDEN_TAG, req);
300             hiddenTag.doStartTag(writer, _hiddenState);
301             hiddenTag.doEndTag(writer);
302         }
303
304         _state.type = INPUT_CHECKBOX;
305
306         TagRenderingBase br = TagRenderingBase.Factory.getRendering(TagRenderingBase.INPUT_BOOLEAN_TAG, req);
307         br.doStartTag(writer, _state);
308
309         if (!ref.isNull())
310             write((String JavaDoc) ref.getRef());
311
312         // Continue processing this page
313
localRelease();
314         return EVAL_PAGE;
315     }
316
317     /**
318      * Release any acquired resources.
319      */

320     protected void localRelease()
321     {
322         super.localRelease();
323
324         _state.clear();
325         _hiddenState.clear();
326     }
327
328     /* ==================================================================
329      *
330      * This tag's publically exposed HTML, CSS, and JavaScript attributes
331      *
332      * ==================================================================
333      */

334
335     /**
336      * Sets the accessKey attribute value. This should key value of the
337      * keyboard navigation key. It is recommended not to use the following
338      * values because there are often used by browsers <code>A, C, E, F, G,
339      * H, V, left arrow, and right arrow</code>.
340      * @param accessKey the accessKey value.
341      * @jsptagref.attributedescription The keyboard navigation key for the element.
342      * The following values are not recommended because they
343      * are often used by browsers: <code>A, C, E, F, G,
344      * H, V, left arrow, and right arrow</code>
345      * @jsptagref.databindable false
346      * @jsptagref.attributesyntaxvalue <i>string_accessKey</i>
347      * @netui:attribute required="false" rtexprvalue="true" type="char"
348      * description="The keyboard navigation key for the element.
349      * The following values are not recommended because they
350      * are often used by browsers: A, C, E, F, G,
351      * H, V, left arrow, and right arrow"
352      */

353     public void setAccessKey(char accessKey)
354     {
355         if (accessKey == 0x00)
356             return;
357         _state.registerAttribute(AbstractHtmlState.ATTR_GENERAL, ACCESSKEY, Character.toString(accessKey));
358     }
359
360     /**
361      * Sets the alt attribute value.
362      * @param alt the alt value.
363      * @jsptagref.attributedescription The alt attribute of the element.
364      * @jsptagref.databindable Read Only
365      * @jsptagref.attributesyntaxvalue <i>string_alt</i>
366      * @netui:attribute required="false" rtexprvalue="true"
367      * description="The alt attribute of the element."
368      */

369     public void setAlt(String JavaDoc alt)
370     {
371         _state.registerAttribute(AbstractHtmlState.ATTR_GENERAL, ALT, alt);
372     }
373
374     /**
375      * Sets the tabIndex of the rendered html tag.
376      * @param tabindex the tab index.
377      * @jsptagref.attributedescription The tabIndex of the rendered HTML tag. This attribute determines the position of the
378      * tag in the sequence of page elements that the user may advance through by pressing the TAB key.
379      * @jsptagref.databindable false
380      * @jsptagref.attributesyntaxvalue <i>string_tabIndex</i>
381      * @netui:attribute required="false" rtexprvalue="true" type="int"
382      * description="The tabIndex of the rendered HTML tag. This attribute determines the position of the
383      * tag in the sequence of page elements that the user may advance through by pressing the TAB key."
384      */

385     public void setTabindex(int tabindex)
386     {
387         _state.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TABINDEX, Integer.toString(tabindex));
388     }
389 }
390
Popular Tags