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