1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.cubby.tags;
17
18 import static org.seasar.cubby.tags.TagUtils.addClassName;
19 import static org.seasar.cubby.tags.TagUtils.contains;
20 import static org.seasar.cubby.tags.TagUtils.errors;
21 import static org.seasar.cubby.tags.TagUtils.getOutputValues;
22 import static org.seasar.cubby.tags.TagUtils.multipleFormValues;
23 import static org.seasar.cubby.tags.TagUtils.toAttr;
24
25 import java.io.IOException;
26 import java.util.Collection;
27 import java.util.Map;
28 import java.util.Map.Entry;
29
30 import javax.servlet.jsp.JspContext;
31 import javax.servlet.jsp.JspException;
32 import javax.servlet.jsp.JspTagException;
33 import javax.servlet.jsp.JspWriter;
34
35 import org.seasar.cubby.action.ActionErrors;
36 import org.seasar.framework.beans.BeanDesc;
37 import org.seasar.framework.beans.PropertyDesc;
38 import org.seasar.framework.beans.factory.BeanDescFactory;
39 import org.seasar.framework.log.Logger;
40 import org.seasar.framework.message.MessageFormatter;
41
42
43
44
45
46
47
48
49 public class SelectTag extends DynamicAttributesTagSupport {
50
51 private static final Logger logger = Logger.getLogger(SelectTag.class);
52
53
54 private String name;
55
56
57 private Object items;
58
59
60 private String labelProperty;
61
62
63 private String valueProperty;
64
65
66
67
68 private Boolean emptyOption = Boolean.TRUE;
69
70
71
72
73 private String emptyOptionLabel;
74
75
76
77
78
79
80
81 public void setItems(final Object items) {
82 this.items = items;
83 }
84
85
86
87
88
89
90
91 public void setLabelProperty(final String labelProperty) {
92 this.labelProperty = labelProperty;
93 }
94
95
96
97
98
99
100
101 public void setValueProperty(final String valueProperty) {
102 this.valueProperty = valueProperty;
103 }
104
105
106
107
108
109
110
111 public void setEmptyOption(final Boolean emptyOption) {
112 this.emptyOption = emptyOption;
113 }
114
115
116
117
118
119
120
121 public void setEmptyOptionLabel(final String emptyOptionLabel) {
122 this.emptyOptionLabel = emptyOptionLabel;
123 }
124
125
126
127
128
129
130
131 public void setName(final String name) {
132 this.name = name;
133 }
134
135
136
137
138 @Override
139 public void doTag() throws JspException, IOException {
140 final JspContext context = this.getJspContext();
141 final JspWriter out = context.getOut();
142 final ActionErrors errors = errors(context);
143 final Map<String, Object> dyn = this.getDynamicAttribute();
144 final String[] outputValues = getOutputValues(this, this.name);
145
146 if (!errors.getFields().get(this.name).isEmpty()) {
147 addClassName(dyn, "fieldError");
148 }
149
150 final Object[] value = multipleFormValues(context, outputValues,
151 this.name);
152
153 out.write("<select name=\"");
154 out.write(this.name);
155 out.write("\" ");
156 out.write(toAttr(dyn));
157 out.write(">\n");
158
159 if (emptyOption) {
160 out.write("<option value=\"\">");
161 out.write(CubbyFunctions.out(emptyOptionLabel));
162 out.write("</option>\n");
163 }
164
165 if (items != null && items.getClass().isArray()) {
166 final OptionWriter optionWriter = new OptionWriter(
167 new BeanItemAdaptor());
168 for (final Object item : (Object[]) items) {
169 optionWriter.write(out, item, value);
170 }
171 } else {
172 final OptionWriter optionWriter;
173 final Collection<?> collection;
174 if (items instanceof Collection) {
175 optionWriter = new OptionWriter(new BeanItemAdaptor());
176 collection = (Collection<?>) items;
177 } else if (items instanceof Map) {
178 optionWriter = new OptionWriter(new EntryItemAdaptor());
179 collection = ((Map<?, ?>) items).entrySet();
180 } else {
181 throw new JspTagException(MessageFormatter.getMessage(
182 "ECUB1001", new Object[] { "items", items.getClass() }));
183 }
184 for (final Object item : collection) {
185 optionWriter.write(out, item, value);
186 }
187 }
188
189 out.write("</select>");
190 }
191
192 private static class OptionWriter {
193
194 private final ItemAdaptor itemAdaptor;
195
196 OptionWriter(final ItemAdaptor itemAdaptor) {
197 this.itemAdaptor = itemAdaptor;
198 }
199
200 void write(final JspWriter out, final Object item, final Object value)
201 throws IOException {
202 out.write("<option value=\"");
203 final String itemValue = DynamicAttributesTagSupport
204 .toString(itemAdaptor.getItemValue(item));
205 final String labelValue = DynamicAttributesTagSupport
206 .toString(itemAdaptor.getLabelValue(item));
207 out.write(CubbyFunctions.out(itemValue));
208 out.write("\" ");
209 out.write(selected(itemValue, value));
210 out.write(">");
211 out.write(CubbyFunctions.out(labelValue));
212 out.write("</option>\n");
213 }
214
215 private String selected(final String value, final Object values) {
216 if (value == null || values == null) {
217 return "";
218 }
219 if (contains(values, value)) {
220 return "selected=\"selected\"";
221 } else {
222 return "";
223 }
224 }
225 }
226
227 private interface ItemAdaptor {
228
229
230
231
232
233
234
235
236 Object getItemValue(Object item);
237
238
239
240
241
242
243
244
245 Object getLabelValue(Object item);
246
247 }
248
249 private class BeanItemAdaptor implements ItemAdaptor {
250
251 BeanItemAdaptor() throws JspTagException {
252 if (valueProperty == null) {
253 throw new JspTagException(MessageFormatter.getMessage(
254 "ECUB1002", new Object[] { "items", "valueProperty" }));
255 }
256 }
257
258
259
260
261 public Object getItemValue(final Object item) {
262 return property(item, valueProperty);
263 }
264
265
266
267
268 public Object getLabelValue(final Object item) {
269 final Object labelValue;
270 if (labelProperty == null) {
271 labelValue = getItemValue(item);
272 } else {
273 labelValue = property(item, labelProperty);
274 }
275 return labelValue;
276 }
277
278 private Object property(final Object bean, final String propertyName) {
279 final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(bean
280 .getClass());
281 final PropertyDesc propertyDesc = beanDesc
282 .getPropertyDesc(propertyName);
283 return propertyDesc.getValue(bean);
284 }
285
286 }
287
288 private class EntryItemAdaptor implements ItemAdaptor {
289
290 EntryItemAdaptor() {
291 if (valueProperty != null) {
292 logger.log("WCUB1001", new Object[] { "items",
293 Map.class.getSimpleName(), "valueProperty",
294 valueProperty,
295 Entry.class.getSimpleName() + "#getKey()" });
296 }
297 if (labelProperty != null) {
298 logger.log("WCUB1002", new Object[] { "items",
299 Map.class.getSimpleName(), "labelProperty",
300 labelProperty,
301 Entry.class.getSimpleName() + "#getValue()" });
302 }
303 }
304
305
306
307
308 public Object getItemValue(final Object item) {
309 return ((Entry<?, ?>) item).getKey();
310 }
311
312
313
314
315 public Object getLabelValue(final Object item) {
316 return ((Entry<?, ?>) item).getValue();
317 }
318
319 }
320
321 }