View Javadoc

1   /*
2    * Copyright 2004-2009 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
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.formValue;
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.Collections;
29  import java.util.HashSet;
30  import java.util.Map;
31  import java.util.Set;
32  
33  import javax.servlet.jsp.JspContext;
34  import javax.servlet.jsp.JspException;
35  import javax.servlet.jsp.JspTagException;
36  import javax.servlet.jsp.JspWriter;
37  
38  import org.seasar.cubby.action.ActionErrors;
39  import org.seasar.cubby.controller.FormWrapper;
40  
41  /**
42   * <code>&lt;input&gt;</code> タグを出力します。
43   * <p>
44   * このタグは type 属性により挙動が変わります。
45   * <table>
46   * <tbody>
47   * <tr>
48   * <td><code>type</code> 属性が <code>checkbox</code> または </code> radio の場合</td>
49   * <td>
50   * <code>value</code> 属性をそのまま <code>value</code> 属性として出力します。 フォームオブジェクトのプロパティ値と
51   * <code>value</code> 属性が一致した場合 <code>checked=&quot;checked&quot;</code> を出力します。
52   * </td>
53   * </tr>
54   * <tr>
55   * <td>上記以外の場合</td>
56   * <td>
57   * <code>value</code> 属性が指定されている場合はそのまま <code>value</code> 属性として出力します。
58   * <code>value</code> 属性が指定されていない場合はフォームオブジェクトのプロパティを <code>value</code>
59   * 属性として出力します。</td>
60   * </tr>
61   * </tbody>
62   * </table>
63   * バリデーションエラーが発生している場合は、入力された値を復元します。
64   * </p>
65   * 
66   * @author agata
67   * @author baba
68   */
69  public class InputTag extends DynamicAttributesSimpleTagSupport {
70  
71  	private static final Set<String> MULTIPLE_VALUE_TYPES;
72  	static {
73  		final Set<String> set = new HashSet<String>();
74  		set.add("checkbox");
75  		set.add("radio");
76  		MULTIPLE_VALUE_TYPES = Collections.unmodifiableSet(set);
77  	}
78  
79  	/** <code>type</code> 属性。 */
80  	private String type;
81  
82  	/** <code>name</code> 属性。 */
83  	private String name;
84  
85  	/** <code>value</code> 属性。 */
86  	private Object value;
87  
88  	/** <code>checkedValue</code> 属性。 */
89  	private String checkedValue;
90  
91  	/** <code>index</code> 属性。 */
92  	private Integer index;
93  
94  	/**
95  	 * <code>type</code> 属性を設定します。
96  	 * 
97  	 * @param type
98  	 *            <code>type</code> 属性
99  	 */
100 	public void setType(final String type) {
101 		this.type = type;
102 	}
103 
104 	/**
105 	 * <code>name</code> 属性を設定します。
106 	 * 
107 	 * @param name
108 	 *            <code>name</code> 属性
109 	 */
110 	public void setName(final String name) {
111 		this.name = name;
112 	}
113 
114 	/**
115 	 * <code>checkedValue</code> 属性を設定します。
116 	 * 
117 	 * @param checkedValue
118 	 *            <code>checkedValue</code> 属性
119 	 */
120 	public void setCheckedValue(final String checkedValue) {
121 		this.checkedValue = checkedValue;
122 	}
123 
124 	/**
125 	 * <code>value</code> 属性を設定します。
126 	 * 
127 	 * @param value
128 	 *            <code>value</code> 属性
129 	 */
130 	public void setValue(final Object value) {
131 		this.value = value;
132 	}
133 
134 	/**
135 	 * <code>index</code> 属性を設定します。
136 	 * 
137 	 * @param index
138 	 *            <code>index</code> 属性
139 	 */
140 	public void setIndex(final Integer index) {
141 		this.index = index;
142 	}
143 
144 	/**
145 	 * {@inheritDoc}
146 	 */
147 	@Override
148 	public void doTag() throws JspException, IOException {
149 		final JspContext context = this.getJspContext();
150 		final JspWriter out = context.getOut();
151 		final ActionErrors errors = errors(context);
152 		final Map<String, Object> dyn = this.getDynamicAttributes();
153 		final FormWrapper formWrapper = getFormWrapper(this);
154 		// final String[] outputValues = getOutputValues(this, this.name);
155 
156 		if (this.index == null) {
157 			if (!errors.getFields().get(this.name).isEmpty()) {
158 				addCSSClassName(dyn, "fieldError");
159 			}
160 		} else {
161 			if (!errors.getIndexedFields().get(this.name).get(index).isEmpty()) {
162 				addCSSClassName(dyn, "fieldError");
163 			}
164 		}
165 
166 		if (MULTIPLE_VALUE_TYPES.contains(this.type)) {
167 			if (this.value == null) {
168 				throw new JspTagException(format("ECUB1003",
169 						MULTIPLE_VALUE_TYPES, "value"));
170 			}
171 			final Object[] values = multipleFormValues(context, formWrapper,
172 					this.name, this.checkedValue);
173 
174 			out.write("<input type=\"");
175 			out.write(type);
176 			out.write("\" name=\"");
177 			out.write(this.name);
178 			out.write("\" value=\"");
179 			out.write(CubbyFunctions.out(this.value));
180 			out.write("\" ");
181 			out.write(toAttr(dyn));
182 			out.write(" ");
183 			out.write(checked(TagUtils.toString(this.value), values));
184 			out.write("/>");
185 		} else {
186 			final Object value = formValue(context, formWrapper, this.name,
187 					this.index, this.value);
188 
189 			out.write("<input type=\"");
190 			out.write(type);
191 			out.write("\" name=\"");
192 			out.write(this.name);
193 			out.write("\" value=\"");
194 			out.write(CubbyFunctions.out(TagUtils.toString(value)));
195 			out.write("\" ");
196 			out.write(toAttr(dyn));
197 			out.write("/>");
198 		}
199 	}
200 
201 	private static String checked(final String value, final Object values) {
202 		if (value == null || values == null) {
203 			return "";
204 		}
205 		if (contains(values, value)) {
206 			return "checked=\"checked\"";
207 		} else {
208 			return "";
209 		}
210 	}
211 
212 }