Line | Hits | Source |
---|---|---|
1 | /* | |
2 | Chrysalis Web Framework [http://chrysalis.sourceforge.net] | |
3 | Copyright (c) 2002, 2003, 2004, Paul Strack | |
4 | ||
5 | All rights reserved. | |
6 | ||
7 | Redistribution and use in source and binary forms, with or without | |
8 | modification, are permitted provided that the following conditions are met: | |
9 | ||
10 | 1. Redistributions of source code must retain the above copyright notice, this | |
11 | list of conditions and the following disclaimer. | |
12 | ||
13 | 2. Redistributions in binary form must reproduce the above copyright notice, | |
14 | this list of conditions and the following disclaimer in the documentation | |
15 | and/or other materials provided with the distribution. | |
16 | ||
17 | 3. Neither the name of the copyright holder nor the names of its contributors | |
18 | may be used to endorse or promote products derived from this software without | |
19 | specific prior written permission. | |
20 | ||
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
22 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
25 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
27 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
31 | */ | |
32 | ||
33 | package org.chwf.taglib.jhtml; | |
34 | ||
35 | import java.io.IOException; | |
36 | import java.util.Arrays; | |
37 | import java.util.Iterator; | |
38 | import java.util.List; | |
39 | import java.util.Map; | |
40 | ||
41 | import javax.servlet.jsp.JspException; | |
42 | import javax.servlet.jsp.JspWriter; | |
43 | ||
44 | import org.chwf.filter.BeanFilter; | |
45 | import org.chwf.plugin.Scripter; | |
46 | import org.chwf.plugin.ValidationData; | |
47 | import org.chwf.taglib.base.TagException; | |
48 | ||
49 | /** | |
50 | * Tag handler for the <code><input></code> tag. | |
51 | * | |
52 | * @author <a href="mailto:pfstrack@users.sourceforge.net">Paul Strack</a> | |
53 | */ | |
54 | 148 | public class InputTag extends FieldTagSupport implements ValidationData { |
55 | ||
56 | /** Constant indicate minimum length for text areas. */ | |
57 | private static final int TEXTAREA_LENGTH = 255; | |
58 | ||
59 | /** Constant for true string values. */ | |
60 | public static final String TRUE_STRING = "true"; | |
61 | ||
62 | /** List of known input types. */ | |
63 | 1 | private static final List TYPES_LIST = |
64 | Arrays.asList( | |
65 | new String[] { | |
66 | TYPE_CHECKBOX, | |
67 | TYPE_HIDDEN, | |
68 | TYPE_FIXED, | |
69 | TYPE_PASSWORD, | |
70 | TYPE_SELECT, | |
71 | TYPE_TEXT, | |
72 | TYPE_TEXTAREA }); | |
73 | ||
74 | /** Boolean datatype. */ | |
75 | private static final String BOOLEAN_TYPE = "java.lang.Boolean"; | |
76 | ||
77 | /** The input type. */ | |
78 | 74 | private String type = null; |
79 | ||
80 | /** Whether validations are supported. */ | |
81 | private Boolean validations; | |
82 | ||
83 | /** The input type. */ | |
84 | 74 | private Map options = null; |
85 | ||
86 | /** | |
87 | * Clean up data for tag handler reuse and pooling. Should be overridden in | |
88 | * tag handler. Subclasses should always invoke their superclass's cleanup | |
89 | * method: <code>super.cleanup()</code> | |
90 | */ | |
91 | public void cleanup() { | |
92 | 3 | super.cleanup(); |
93 | 3 | this.type = null; |
94 | 3 | this.validations = null; |
95 | 3 | this.options = null; |
96 | 3 | } |
97 | ||
98 | /** | |
99 | * Calls superclass method. Is present here because of a bug in some servlet | |
100 | * engines that requires tag attibute setters to be defined in the tag class | |
101 | * itself. | |
102 | * | |
103 | * @param objectName The object name. | |
104 | * @throws JspException For errors. | |
105 | */ | |
106 | public void setObject(String objectName) throws JspException { | |
107 | 1 | super.setObject(objectName); |
108 | 1 | } |
109 | ||
110 | /** | |
111 | * Calls superclass method. Is present here because of a bug in some servlet | |
112 | * engines that requires tag attibute setters to be defined in the tag class | |
113 | * itself. | |
114 | * | |
115 | * @param property The property name. | |
116 | * @throws JspException For errors. | |
117 | */ | |
118 | public void setProperty(String property) throws JspException { | |
119 | 32 | super.setProperty(property); |
120 | 32 | } |
121 | ||
122 | /** | |
123 | * Calls superclass method. Is present here because of a bug in some servlet | |
124 | * engines that requires tag attibute setters to be defined in the tag class | |
125 | * itself. | |
126 | * | |
127 | * @param name The field name. | |
128 | */ | |
129 | public void setName(String name) { | |
130 | 2 | super.setName(name); |
131 | 2 | } |
132 | ||
133 | /** | |
134 | * Set the input element type. Optional. The type value is converted | |
135 | * to lowercase for consistency with the XHTML standard. | |
136 | * | |
137 | * @param type The input type. | |
138 | * @throws JspException If the type is not one of the known input | |
139 | * element types, defined as TYPE_XXX constants. | |
140 | */ | |
141 | public void setType(String type) throws JspException { | |
142 | 17 | type = type.toLowerCase(); |
143 | 17 | if (!TYPES_LIST.contains(type)) { |
144 | 2 | throw new TagException( |
145 | JhtmlMessages.MESSAGE_INVALID_INPUT_TAG_TYPE, | |
146 | new Object[] { type, TYPES_LIST }); | |
147 | } | |
148 | 15 | this.type = type; |
149 | 15 | } |
150 | ||
151 | /** | |
152 | * Gets the input element type. If no type is defined, it attempts | |
153 | * to deduce the type for form object metadata. | |
154 | * | |
155 | * <ul> | |
156 | * <li>Readonly types are printed as fixed fields.</li> | |
157 | * <li>Fields with options are printed as select lists.</li> | |
158 | * <li>Boolean fields are printed as checkboxes.</li> | |
159 | * <li>Fields whose maxlength > 255 are printed as textareas.</li> | |
160 | * <li>Otherwise, the field is printed as a text field.</li> | |
161 | * </ul> | |
162 | * | |
163 | * @return The input type. | |
164 | * @throws JspException If the property cannot be initialized | |
165 | */ | |
166 | public String getType() throws JspException { | |
167 | 45 | if (this.type == null) { |
168 | // Check to see if field is readonly; default to "fixed": | |
169 | 15 | Object attribute = getPropertyAttribute(BeanFilter.ATTRIBUTE_READONLY); |
170 | 15 | if ((attribute != null) && (attribute instanceof Boolean)) { |
171 | 3 | Boolean readonly = (Boolean) attribute; |
172 | 3 | if (readonly.booleanValue()) { |
173 | 3 | this.type = TYPE_FIXED; |
174 | } | |
175 | } | |
176 | } | |
177 | ||
178 | 45 | if (this.type == null) { |
179 | // Check to see if field has options; default to "select": | |
180 | 12 | Object attribute = getPropertyAttribute(BeanFilter.ATTRIBUTE_OPTIONS); |
181 | 12 | if ((attribute != null) && (attribute instanceof Map)) { |
182 | 1 | this.type = TYPE_SELECT; |
183 | } | |
184 | } | |
185 | ||
186 | 45 | if (this.type == null) { |
187 | // Check to see if field boolean; default to "checkbox": | |
188 | 11 | Object attribute = getPropertyAttribute(BeanFilter.ATTRIBUTE_DATATYPE); |
189 | 11 | if ((attribute != null) && (attribute.toString().equals(BOOLEAN_TYPE))) { |
190 | 1 | this.type = TYPE_CHECKBOX; |
191 | } | |
192 | } | |
193 | ||
194 | 45 | if (this.type == null) { |
195 | // Check to see if maxlength > 255; default to "textarea": | |
196 | 10 | Object attribute = getPropertyAttribute(BeanFilter.ATTRIBUTE_MAXLENGTH); |
197 | 10 | if ((attribute != null) && (attribute instanceof Number)) { |
198 | 2 | Number maxlength = (Number) attribute; |
199 | 2 | if (maxlength.intValue() > TEXTAREA_LENGTH) { |
200 | 2 | this.type = TYPE_TEXTAREA; |
201 | } | |
202 | } | |
203 | } | |
204 | ||
205 | 45 | if (this.type == null) { |
206 | // If all else fails; default to "text": | |
207 | 8 | this.type = TYPE_TEXT; |
208 | } | |
209 | ||
210 | 45 | return this.type; |
211 | } | |
212 | ||
213 | /** | |
214 | * Whether validations are supported. If not specified, defaults to | |
215 | * value in nesting formtag. | |
216 | * | |
217 | * @param validations Whether validations are supported. | |
218 | */ | |
219 | public void setValidations(Boolean validations) { | |
220 | 4 | this.validations = validations; |
221 | 4 | } |
222 | ||
223 | /** | |
224 | * Whether validations are supported. May be null. | |
225 | * | |
226 | * @return Whether validations are supported. | |
227 | */ | |
228 | public Boolean getValidations() { | |
229 | 23 | if ((this.validations == null) && (getFormTag() != null)) { |
230 | 19 | this.validations = getFormTag().getValidations(); |
231 | } | |
232 | 23 | if (this.validations == null) { |
233 | 19 | this.validations = Boolean.TRUE; |
234 | } | |
235 | 23 | return validations; |
236 | } | |
237 | ||
238 | /** | |
239 | * The name of the web application variable containing input items options. | |
240 | * | |
241 | * @param options The variable name for options. | |
242 | */ | |
243 | public void setOptions(String options) { | |
244 | 3 | Object optionMap = this.pageContext.findAttribute(options); |
245 | 3 | if (optionMap instanceof Map) { |
246 | 3 | this.options = (Map) optionMap; |
247 | } | |
248 | 3 | } |
249 | ||
250 | /** | |
251 | * The option map for select lists. Uses the options map specified by the | |
252 | * options attribute or the bean filters OPTIONS attribute. | |
253 | * | |
254 | * @return The option map. | |
255 | * @throws JspException If the option map cannot be found. | |
256 | */ | |
257 | public Map getOptionsMap() throws JspException { | |
258 | 4 | if (this.options == null) { |
259 | 1 | Object attribute = getPropertyAttribute(BeanFilter.ATTRIBUTE_OPTIONS); |
260 | 1 | if ((attribute == null) || !(attribute instanceof Map)) { |
261 | 0 | throw new TagException( |
262 | JhtmlMessages.MESSAGE_SELECT_TAG_REQUIRES_OPTIONS); | |
263 | } | |
264 | 1 | this.options = (Map) attribute; |
265 | } | |
266 | 4 | return this.options; |
267 | } | |
268 | ||
269 | /** | |
270 | * Pass-through attribute. Same meaning as "class" in HTML. | |
271 | * | |
272 | * @param value The attribute value. | |
273 | */ | |
274 | public void setStyleClass(String value) { | |
275 | 1 | addAttribute("class", value); |
276 | 1 | } |
277 | ||
278 | /** | |
279 | * Pass-through attribute. Same meaning as in HTML. | |
280 | * | |
281 | * @param value The attribute value. | |
282 | */ | |
283 | public void setId(String value) { | |
284 | 1 | addAttribute("id", value); |
285 | 1 | } |
286 | ||
287 | /** | |
288 | * Pass-through attribute. Same meaning as in HTML. | |
289 | * | |
290 | * @param value The attribute value. | |
291 | */ | |
292 | public void setLang(String value) { | |
293 | 1 | addAttribute("lang", value); |
294 | 1 | } |
295 | ||
296 | /** | |
297 | * Pass-through attribute. Same meaning as in HTML. | |
298 | * | |
299 | * @param value The attribute value. | |
300 | */ | |
301 | public void setStyle(String value) { | |
302 | 1 | addAttribute("style", value); |
303 | 1 | } |
304 | ||
305 | /** | |
306 | * Pass-through attribute. Same meaning as in HTML. | |
307 | * | |
308 | * @param value The attribute value. | |
309 | */ | |
310 | public void setTitle(String value) { | |
311 | 1 | addAttribute("title", value); |
312 | 1 | } |
313 | ||
314 | // input attributes | |
315 | ||
316 | /** | |
317 | * Pass-through attribute. Same meaning as in HTML. | |
318 | * | |
319 | * @param value The attribute value. | |
320 | */ | |
321 | public void setAccept(String value) { | |
322 | 1 | addAttribute("accept", value); |
323 | 1 | } |
324 | ||
325 | /** | |
326 | * Pass-through attribute. Same meaning as in HTML. | |
327 | * | |
328 | * @param value The attribute value. | |
329 | */ | |
330 | public void setAccesskey(String value) { | |
331 | 1 | addAttribute("accesskey", value); |
332 | 1 | } |
333 | ||
334 | /** | |
335 | * Pass-through attribute. Same meaning as in HTML. | |
336 | * | |
337 | * @param value The attribute value. | |
338 | */ | |
339 | public void setDisabled(String value) { | |
340 | 1 | addAttribute("disabled", value); |
341 | 1 | } |
342 | ||
343 | /** | |
344 | * Pass-through attribute. Same meaning as in HTML. | |
345 | * | |
346 | * @param value The attribute value. | |
347 | */ | |
348 | public void setMaxlength(String value) { | |
349 | 1 | addAttribute("maxlength", value); |
350 | 1 | } |
351 | ||
352 | /** | |
353 | * Pass-through attribute. Same meaning as in HTML. | |
354 | * | |
355 | * @param value The attribute value. | |
356 | */ | |
357 | public void setSize(String value) { | |
358 | 2 | addAttribute("size", value); |
359 | 2 | } |
360 | ||
361 | // textarea attributes | |
362 | ||
363 | /** | |
364 | * Pass-through attribute. Same meaning as in HTML. | |
365 | * | |
366 | * @param value The attribute value. | |
367 | */ | |
368 | public void setCols(String value) { | |
369 | 1 | addAttribute("cols", value); |
370 | 1 | } |
371 | ||
372 | /** | |
373 | * Pass-through attribute. Same meaning as in HTML. | |
374 | * | |
375 | * @param value The attribute value. | |
376 | */ | |
377 | public void setRows(String value) { | |
378 | 1 | addAttribute("rows", value); |
379 | 1 | } |
380 | ||
381 | /** | |
382 | * Pass-through attribute. Same meaning as in HTML. | |
383 | * | |
384 | * @param value The attribute value. | |
385 | */ | |
386 | public void setWrap(String value) { | |
387 | 1 | addAttribute("wrap", value); |
388 | 1 | } |
389 | ||
390 | /** | |
391 | * Initialization. Makes "cols" attribute default to value of "size". | |
392 | * | |
393 | * @throws JspException For errors. | |
394 | */ | |
395 | public void init() throws JspException { | |
396 | 17 | super.init(); |
397 | 17 | String size = getAttribute("size"); |
398 | 17 | if ((size != null) && (getAttribute("cols") == null)) { |
399 | 2 | addAttribute("cols", size); |
400 | } | |
401 | 17 | } |
402 | ||
403 | /** | |
404 | * Print the input element. | |
405 | * | |
406 | * @return SKIP_BODY | |
407 | * @throws JspException If the property cannot be initialized. | |
408 | * @throws IOException For IO exceptions. | |
409 | */ | |
410 | public int doStart() throws IOException, JspException { | |
411 | 11 | printInputElement(); |
412 | 11 | return SKIP_BODY; |
413 | } | |
414 | ||
415 | /** | |
416 | * Print the input element. | |
417 | * | |
418 | * @throws JspException If the property cannot be initialized. | |
419 | * @throws IOException For IO exceptions. | |
420 | */ | |
421 | void printInputElement() throws JspException, IOException { | |
422 | 15 | String type = getType(); |
423 | 15 | if (type.equals(TYPE_CHECKBOX)) { |
424 | 2 | printCheckboxTag(); |
425 | 13 | } else if (type.equals(TYPE_FIXED)) { |
426 | 1 | printFixedTag(); |
427 | 12 | } else if (type.equals(TYPE_HIDDEN)) { |
428 | 1 | printHiddenTag(); |
429 | 11 | } else if (type.equals(TYPE_PASSWORD)) { |
430 | 1 | printPasswordTag(); |
431 | 10 | } else if (type.equals(TYPE_SELECT)) { |
432 | 2 | printSelectTag(); |
433 | 8 | } else if (type.equals(TYPE_TEXT)) { |
434 | 6 | printTextTag(); |
435 | 2 | } else if (type.equals(TYPE_TEXTAREA)) { |
436 | 2 | printTextareaTag(); |
437 | } else { | |
438 | 0 | throw new TagException( |
439 | JhtmlMessages.MESSAGE_INVALID_INPUT_TAG_TYPE, | |
440 | new Object[] { type, TYPES_LIST }); | |
441 | } | |
442 | ||
443 | 15 | if (Boolean.TRUE.equals(getValidations())) { |
444 | 15 | Scripter.getInstance().printValidations(this, pageContext.getOut()); |
445 | } | |
446 | 15 | } |
447 | ||
448 | /** | |
449 | * Print checkbox field. | |
450 | * | |
451 | * @throws IOException For IO exceptions. | |
452 | * @throws JspException If the value cannot be found. | |
453 | */ | |
454 | private void printCheckboxTag() throws IOException, JspException { | |
455 | 2 | JspWriter out = pageContext.getOut(); |
456 | 2 | out.print("<input type='checkbox' name='"); |
457 | 2 | out.print(getName()); |
458 | 2 | out.print("' value='true'"); |
459 | 2 | Object value = getFieldValue(); |
460 | 2 | if (TRUE_STRING.equals(value)) { |
461 | 1 | out.print(" checked='checked'"); |
462 | } | |
463 | 2 | printAttributes(); |
464 | 2 | out.print(" />"); |
465 | 2 | } |
466 | ||
467 | /** | |
468 | * Print fixed field. | |
469 | * | |
470 | * @throws IOException For IO exceptions. | |
471 | * @throws JspException If the value cannot be found. | |
472 | */ | |
473 | private void printFixedTag() throws IOException, JspException { | |
474 | 1 | JspWriter out = pageContext.getOut(); |
475 | 1 | out.print(getFieldValue()); |
476 | 1 | out.print("<input type='hidden' name='"); |
477 | 1 | out.print(getName()); |
478 | 1 | out.print("' value='"); |
479 | 1 | out.print(getFieldValue()); |
480 | 1 | out.print("'"); |
481 | 1 | printAttributes(); |
482 | 1 | out.print(" />"); |
483 | 1 | } |
484 | ||
485 | /** | |
486 | * Print hidden field. | |
487 | * | |
488 | * @throws IOException For IO exceptions. | |
489 | * @throws JspException If the value cannot be found. | |
490 | */ | |
491 | private void printHiddenTag() throws IOException, JspException { | |
492 | 1 | JspWriter out = pageContext.getOut(); |
493 | 1 | out.print("<input type='hidden' name='"); |
494 | 1 | out.print(getName()); |
495 | 1 | out.print("' value='"); |
496 | 1 | out.print(getFieldValue()); |
497 | 1 | out.print("'"); |
498 | 1 | printAttributes(); |
499 | 1 | out.print(" />"); |
500 | 1 | } |
501 | ||
502 | /** | |
503 | * Print password field. | |
504 | * | |
505 | * @throws IOException For IO exceptions. | |
506 | * @throws JspException If the value cannot be found. | |
507 | */ | |
508 | private void printPasswordTag() throws IOException, JspException { | |
509 | 1 | JspWriter out = pageContext.getOut(); |
510 | 1 | out.print("<input type='password' name='"); |
511 | 1 | out.print(getName()); |
512 | 1 | out.print("' value='"); |
513 | 1 | out.print(getFieldValue()); |
514 | 1 | out.print("'"); |
515 | 1 | printAttributes(); |
516 | 1 | out.print(" />"); |
517 | 1 | } |
518 | ||
519 | /** | |
520 | * Print select field. | |
521 | * | |
522 | * @throws IOException For IO exceptions. | |
523 | * @throws JspException If the value cannot be found. | |
524 | */ | |
525 | private void printSelectTag() throws IOException, JspException { | |
526 | 2 | Map options = getOptionsMap(); |
527 | 2 | Iterator keys = options.keySet().iterator(); |
528 | ||
529 | 2 | JspWriter out = pageContext.getOut(); |
530 | 2 | out.print("<select name='"); |
531 | 2 | out.print(getName()); |
532 | 2 | out.print("'"); |
533 | 2 | printAttributes(); |
534 | 2 | out.print(">"); |
535 | ||
536 | 2 | String value = getFieldValue(); |
537 | 10 | while (keys.hasNext()) { |
538 | 6 | Object key = keys.next(); |
539 | 6 | out.print("<option value='"); |
540 | 6 | out.print(key.toString()); |
541 | 6 | if (key.toString().equals(value)) { |
542 | 2 | out.print("' selected='selected"); |
543 | } | |
544 | 6 | out.print("'>"); |
545 | 6 | out.print(options.get(key)); |
546 | 6 | out.print("</option>"); |
547 | } | |
548 | 2 | out.print("</select>"); |
549 | 2 | } |
550 | ||
551 | /** | |
552 | * Print textarea field. | |
553 | * | |
554 | * @throws IOException For IO exceptions. | |
555 | * @throws JspException If the property cannot be initialized. | |
556 | */ | |
557 | private void printTextareaTag() throws IOException, JspException { | |
558 | 2 | JspWriter out = pageContext.getOut(); |
559 | 2 | out.print("<textarea name='"); |
560 | 2 | out.print(getName()); |
561 | 2 | out.print("'"); |
562 | 2 | printAttributes(); |
563 | 2 | out.print(">"); |
564 | 2 | out.print(getFieldValue()); |
565 | 2 | out.print("</textarea>"); |
566 | 2 | } |
567 | ||
568 | /** | |
569 | * Print text field. | |
570 | * | |
571 | * @throws IOException For IO exceptions. | |
572 | * @throws JspException If the property cannot be initialized. | |
573 | */ | |
574 | private void printTextTag() throws IOException, JspException { | |
575 | 6 | JspWriter out = pageContext.getOut(); |
576 | 6 | out.print("<input type='text' name='"); |
577 | 6 | out.print(getName()); |
578 | 6 | out.print("' value='"); |
579 | 6 | out.print(getFieldValue()); |
580 | 6 | out.print("'"); |
581 | 6 | printAttributes(); |
582 | 6 | out.print(" />"); |
583 | 6 | } |
584 | } |
this report was generated by version 1.0.5 of jcoverage. |
copyright © 2003, jcoverage ltd. all rights reserved. |