View Javadoc

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