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 }