KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > taglib > html > OptionsTag


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

18
19 package org.apache.struts.taglib.html;
20
21 import java.lang.reflect.InvocationTargetException JavaDoc;
22 import java.util.Arrays JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Enumeration JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Map JavaDoc;
27
28 import javax.servlet.jsp.JspException JavaDoc;
29 import javax.servlet.jsp.tagext.TagSupport JavaDoc;
30
31 import org.apache.commons.beanutils.PropertyUtils;
32 import org.apache.struts.util.IteratorAdapter;
33 import org.apache.struts.taglib.TagUtils;
34 import org.apache.struts.util.MessageResources;
35
36 /**
37  * Tag for creating multiple <select> options from a collection. The
38  * associated values displayed to the user may optionally be specified by a
39  * second collection, or will be the same as the values themselves. Each
40  * collection may be an array of objects, a Collection, an Enumeration,
41  * an Iterator, or a Map.
42  * <b>NOTE</b> - This tag requires a Java2 (JDK 1.2 or later) platform.
43  *
44  */

45
46 public class OptionsTag extends TagSupport JavaDoc {
47
48     /**
49      * The message resources for this package.
50      */

51     protected static MessageResources messages =
52         MessageResources.getMessageResources(Constants.Package + ".LocalStrings");
53
54     /**
55      * The name of the collection containing beans that have properties to
56      * provide both the values and the labels (identified by the
57      * <code>property</code> and <code>labelProperty</code> attributes).
58      */

59     protected String JavaDoc collection = null;
60
61     public String JavaDoc getCollection() {
62         return (this.collection);
63     }
64
65     public void setCollection(String JavaDoc collection) {
66         this.collection = collection;
67     }
68
69     /**
70      * Should the label values be filtered for HTML sensitive characters?
71      */

72     protected boolean filter = true;
73
74     public boolean getFilter() {
75         return filter;
76     }
77
78     public void setFilter(boolean filter) {
79         this.filter = filter;
80     }
81
82     /**
83      * The name of the bean containing the labels collection.
84      */

85     protected String JavaDoc labelName = null;
86
87     public String JavaDoc getLabelName() {
88         return labelName;
89     }
90
91     public void setLabelName(String JavaDoc labelName) {
92         this.labelName = labelName;
93     }
94
95     /**
96      * The bean property containing the labels collection.
97      */

98     protected String JavaDoc labelProperty = null;
99
100     public String JavaDoc getLabelProperty() {
101         return labelProperty;
102     }
103
104     public void setLabelProperty(String JavaDoc labelProperty) {
105         this.labelProperty = labelProperty;
106     }
107
108     /**
109      * The name of the bean containing the values collection.
110      */

111     protected String JavaDoc name = null;
112
113     public String JavaDoc getName() {
114         return name;
115     }
116
117     public void setName(String JavaDoc name) {
118         this.name = name;
119     }
120
121     /**
122      * The name of the property to use to build the values collection.
123      */

124     protected String JavaDoc property = null;
125
126     public String JavaDoc getProperty() {
127         return property;
128     }
129
130     public void setProperty(String JavaDoc property) {
131         this.property = property;
132     }
133
134     /**
135      * The style associated with this tag.
136      */

137     private String JavaDoc style = null;
138
139     public String JavaDoc getStyle() {
140         return style;
141     }
142
143     public void setStyle(String JavaDoc style) {
144         this.style = style;
145     }
146
147     /**
148      * The named style class associated with this tag.
149      */

150     private String JavaDoc styleClass = null;
151
152     public String JavaDoc getStyleClass() {
153         return styleClass;
154     }
155
156     public void setStyleClass(String JavaDoc styleClass) {
157         this.styleClass = styleClass;
158     }
159
160     /**
161      * Process the start of this tag.
162      *
163      * @exception JspException if a JSP exception has occurred
164      */

165
166     public int doStartTag() throws JspException JavaDoc {
167         return SKIP_BODY;
168     }
169
170     /**
171      * Process the end of this tag.
172      *
173      * @exception JspException if a JSP exception has occurred
174      */

175     public int doEndTag() throws JspException JavaDoc {
176
177         // Acquire the select tag we are associated with
178
SelectTag selectTag = (SelectTag) pageContext.getAttribute(Constants.SELECT_KEY);
179         if (selectTag == null) {
180             throw new JspException JavaDoc(messages.getMessage("optionsTag.select"));
181         }
182         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
183
184         // If a collection was specified, use that mode to render options
185
if (collection != null) {
186             Iterator JavaDoc collIterator = getIterator(collection, null);
187             while (collIterator.hasNext()) {
188
189                 Object JavaDoc bean = collIterator.next();
190                 Object JavaDoc value = null;
191                 Object JavaDoc label = null;
192
193                 try {
194                     value = PropertyUtils.getProperty(bean, property);
195                     if (value == null) {
196                         value = "";
197                     }
198                 } catch (IllegalAccessException JavaDoc e) {
199                     throw new JspException JavaDoc(
200                         messages.getMessage("getter.access", property, collection));
201                 } catch (InvocationTargetException JavaDoc e) {
202                     Throwable JavaDoc t = e.getTargetException();
203                     throw new JspException JavaDoc(
204                         messages.getMessage("getter.result", property, t.toString()));
205                 } catch (NoSuchMethodException JavaDoc e) {
206                     throw new JspException JavaDoc(
207                         messages.getMessage("getter.method", property, collection));
208                 }
209
210                 try {
211                     if (labelProperty != null) {
212                         label = PropertyUtils.getProperty(bean, labelProperty);
213                     } else {
214                         label = value;
215                     }
216
217                     if (label == null) {
218                         label = "";
219                     }
220                 } catch (IllegalAccessException JavaDoc e) {
221                     throw new JspException JavaDoc(
222                         messages.getMessage("getter.access", labelProperty, collection));
223                 } catch (InvocationTargetException JavaDoc e) {
224                     Throwable JavaDoc t = e.getTargetException();
225                     throw new JspException JavaDoc(
226                         messages.getMessage("getter.result", labelProperty, t.toString()));
227                 } catch (NoSuchMethodException JavaDoc e) {
228                     throw new JspException JavaDoc(
229                         messages.getMessage("getter.method", labelProperty, collection));
230                 }
231
232                 String JavaDoc stringValue = value.toString();
233                 addOption(sb, stringValue, label.toString(), selectTag.isMatched(stringValue));
234
235             }
236
237         }
238
239         // Otherwise, use the separate iterators mode to render options
240
else {
241
242             // Construct iterators for the values and labels collections
243
Iterator JavaDoc valuesIterator = getIterator(name, property);
244             Iterator JavaDoc labelsIterator = null;
245             if ((labelName == null) && (labelProperty == null)) {
246                 labelsIterator = getIterator(name, property); // Same coll.
247
} else {
248                 labelsIterator = getIterator(labelName, labelProperty);
249             }
250
251             // Render the options tags for each element of the values coll.
252
while (valuesIterator.hasNext()) {
253                 Object JavaDoc valueObject = valuesIterator.next();
254                 if (valueObject == null) {
255                     valueObject = "";
256                 }
257                 String JavaDoc value = valueObject.toString();
258                 String JavaDoc label = value;
259                 if (labelsIterator.hasNext()) {
260                     Object JavaDoc labelObject = labelsIterator.next();
261                     if (labelObject == null) {
262                         labelObject = "";
263                     }
264                     label = labelObject.toString();
265                 }
266                 addOption(sb, value, label, selectTag.isMatched(value));
267             }
268         }
269
270         TagUtils.getInstance().write(pageContext, sb.toString());
271
272         return EVAL_PAGE;
273
274     }
275
276     /**
277      * Release any acquired resources.
278      */

279     public void release() {
280
281         super.release();
282         collection = null;
283         filter = true;
284         labelName = null;
285         labelProperty = null;
286         name = null;
287         property = null;
288         style = null;
289         styleClass = null;
290     }
291
292     // ------------------------------------------------------ Protected Methods
293

294     /**
295      * Add an option element to the specified StringBuffer based on the
296      * specified parameters.
297      *<p>
298      * Note that this tag specifically does not support the
299      * <code>styleId</code> tag attribute, which causes the HTML
300      * <code>id</code> attribute to be emitted. This is because the HTML
301      * specification states that all "id" attributes in a document have to be
302      * unique. This tag will likely generate more than one <code>option</code>
303      * element element, but it cannot use the same <code>id</code> value. It's
304      * conceivable some sort of mechanism to supply an array of <code>id</code>
305      * values could be devised, but that doesn't seem to be worth the trouble.
306      *
307      * @param sb StringBuffer accumulating our results
308      * @param value Value to be returned to the server for this option
309      * @param label Value to be shown to the user for this option
310      * @param matched Should this value be marked as selected?
311      */

312     protected void addOption(StringBuffer JavaDoc sb, String JavaDoc value, String JavaDoc label, boolean matched) {
313
314         sb.append("<option value=\"");
315         if (filter) {
316             sb.append(TagUtils.getInstance().filter(value));
317         } else {
318             sb.append(value);
319         }
320         sb.append("\"");
321         if (matched) {
322             sb.append(" selected=\"selected\"");
323         }
324         if (style != null) {
325             sb.append(" style=\"");
326             sb.append(style);
327             sb.append("\"");
328         }
329         if (styleClass != null) {
330             sb.append(" class=\"");
331             sb.append(styleClass);
332             sb.append("\"");
333         }
334         
335         sb.append(">");
336         
337         if (filter) {
338             sb.append(TagUtils.getInstance().filter(label));
339         } else {
340             sb.append(label);
341         }
342         
343         sb.append("</option>\r\n");
344
345     }
346
347     /**
348      * Return an iterator for the option labels or values, based on our
349      * configured properties.
350      *
351      * @param name Name of the bean attribute (if any)
352      * @param property Name of the bean property (if any)
353      *
354      * @exception JspException if an error occurs
355      */

356     protected Iterator JavaDoc getIterator(String JavaDoc name, String JavaDoc property) throws JspException JavaDoc {
357
358         // Identify the bean containing our collection
359
String JavaDoc beanName = name;
360         if (beanName == null) {
361             beanName = Constants.BEAN_KEY;
362         }
363
364         Object JavaDoc bean = TagUtils.getInstance().lookup(pageContext, beanName, null);
365         if (bean == null) {
366             throw new JspException JavaDoc(messages.getMessage("getter.bean", beanName));
367         }
368
369         // Identify the collection itself
370
Object JavaDoc collection = bean;
371         if (property != null) {
372             try {
373                 collection = PropertyUtils.getProperty(bean, property);
374                 if (collection == null) {
375                     throw new JspException JavaDoc(messages.getMessage("getter.property", property));
376                 }
377             } catch (IllegalAccessException JavaDoc e) {
378                 throw new JspException JavaDoc(messages.getMessage("getter.access", property, name));
379             } catch (InvocationTargetException JavaDoc e) {
380                 Throwable JavaDoc t = e.getTargetException();
381                 throw new JspException JavaDoc(
382                     messages.getMessage("getter.result", property, t.toString()));
383             } catch (NoSuchMethodException JavaDoc e) {
384                 throw new JspException JavaDoc(messages.getMessage("getter.method", property, name));
385             }
386         }
387
388         // Construct and return an appropriate iterator
389
if (collection.getClass().isArray()) {
390             collection = Arrays.asList((Object JavaDoc[]) collection);
391         }
392
393         if (collection instanceof Collection JavaDoc) {
394             return (((Collection JavaDoc) collection).iterator());
395
396         } else if (collection instanceof Iterator JavaDoc) {
397             return ((Iterator JavaDoc) collection);
398
399         } else if (collection instanceof Map JavaDoc) {
400             return (((Map JavaDoc) collection).entrySet().iterator());
401
402         } else if (collection instanceof Enumeration JavaDoc) {
403             return new IteratorAdapter((Enumeration JavaDoc) collection);
404
405         } else {
406             throw new JspException JavaDoc(
407                 messages.getMessage("optionsTag.iterator", collection.toString()));
408         }
409     }
410
411 }
412
Popular Tags