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.internal.util.LogMessages.format;
19 import static org.seasar.cubby.tags.TagUtils.addCSSClassName;
20 import static org.seasar.cubby.tags.TagUtils.contains;
21 import static org.seasar.cubby.tags.TagUtils.errors;
22 import static org.seasar.cubby.tags.TagUtils.getFormWrapper;
23 import static org.seasar.cubby.tags.TagUtils.multipleFormValues;
24 import static org.seasar.cubby.tags.TagUtils.toAttr;
25
26 import java.io.IOException;
27 import java.util.Collection;
28 import java.util.Map;
29 import java.util.Map.Entry;
30
31 import javax.servlet.jsp.JspContext;
32 import javax.servlet.jsp.JspException;
33 import javax.servlet.jsp.JspTagException;
34 import javax.servlet.jsp.JspWriter;
35
36 import org.seasar.cubby.action.ActionErrors;
37 import org.seasar.cubby.controller.FormWrapper;
38 import org.seasar.cubby.spi.beans.Attribute;
39 import org.seasar.cubby.spi.beans.BeanDesc;
40 import org.seasar.cubby.spi.beans.BeanDescFactory;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44
45
46
47
48
49
50 public class SelectTag extends DynamicAttributesSimpleTagSupport {
51
52
53 private String name;
54
55
56 private Object items;
57
58
59 private String labelProperty;
60
61
62 private String valueProperty;
63
64
65 private Boolean emptyOption = Boolean.TRUE;
66
67
68 private String emptyOptionLabel;
69
70
71
72
73
74
75
76 public void setItems(final Object items) {
77 this.items = items;
78 }
79
80
81
82
83
84
85
86
87 public void setLabelProperty(final String labelProperty) {
88 this.labelProperty = labelProperty;
89 }
90
91
92
93
94
95
96
97
98 public void setValueProperty(final String valueProperty) {
99 this.valueProperty = valueProperty;
100 }
101
102
103
104
105
106
107
108 public void setEmptyOption(final Boolean emptyOption) {
109 this.emptyOption = emptyOption;
110 }
111
112
113
114
115
116
117
118 public void setEmptyOptionLabel(final String emptyOptionLabel) {
119 this.emptyOptionLabel = emptyOptionLabel;
120 }
121
122
123
124
125
126
127
128 public void setName(final String name) {
129 this.name = name;
130 }
131
132
133
134
135 @Override
136 public void doTag() throws JspException, IOException {
137 if (items == null) {
138 throw new JspTagException(format("ECUB1005"));
139 }
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.getDynamicAttributes();
144 final FormWrapper formWrapper = getFormWrapper(this);
145
146 if (!errors.getFields().get(this.name).isEmpty()) {
147 addCSSClassName(dyn, "fieldError");
148 }
149
150 final Object[] value = multipleFormValues(context, formWrapper,
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(format("ECUB1001", "items",
182 items == null ? null : 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 = TagUtils.toString(itemAdaptor
204 .getItemValue(item));
205 final String labelValue = TagUtils.toString(itemAdaptor
206 .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(format("ECUB1002", "items",
254 "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
279
280
281
282
283
284
285
286
287 private Object property(final Object bean, final String propertyName) {
288 final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(bean
289 .getClass());
290 final Attribute attribute = beanDesc
291 .getPropertyAttribute(propertyName);
292 return attribute.getValue(bean);
293 }
294
295 }
296
297 private class EntryItemAdaptor implements ItemAdaptor {
298
299 EntryItemAdaptor() {
300 if (valueProperty != null) {
301 final Logger logger = LoggerFactory.getLogger(SelectTag.class);
302 if (logger.isWarnEnabled()) {
303 logger.warn(format("WCUB1001", "items", Map.class
304 .getSimpleName(), "valueProperty", valueProperty,
305 Entry.class.getSimpleName() + "#getKey()"));
306 }
307 }
308 if (labelProperty != null) {
309 final Logger logger = LoggerFactory.getLogger(SelectTag.class);
310 if (logger.isWarnEnabled()) {
311 logger.warn(format("WCUB1002", "items", Map.class
312 .getSimpleName(), "labelProperty", labelProperty,
313 Entry.class.getSimpleName() + "#getValue()"));
314 }
315 }
316 }
317
318
319
320
321 public Object getItemValue(final Object item) {
322 return ((Entry<?, ?>) item).getKey();
323 }
324
325
326
327
328 public Object getLabelValue(final Object item) {
329 return ((Entry<?, ?>) item).getValue();
330 }
331
332 }
333
334 }