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