View Javadoc

1   /*
2    * Copyright 2004-2008 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.CubbyConstants.ATTR_CONTEXT_PATH;
19  import static org.seasar.cubby.tags.TagUtils.toAttr;
20  
21  import java.io.IOException;
22  import java.util.HashMap;
23  import java.util.Map;
24  
25  import javax.servlet.http.HttpServletResponse;
26  import javax.servlet.jsp.JspException;
27  import javax.servlet.jsp.JspWriter;
28  import javax.servlet.jsp.PageContext;
29  import javax.servlet.jsp.tagext.BodyContent;
30  import javax.servlet.jsp.tagext.BodyTagSupport;
31  import javax.servlet.jsp.tagext.DynamicAttributes;
32  
33  import org.seasar.cubby.controller.FormWrapper;
34  import org.seasar.cubby.controller.FormWrapperFactory;
35  import org.seasar.framework.container.S2Container;
36  import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
37  
38  /**
39   * フォームを出力するタグライブラリ。
40   * <p>
41   * {@link InputTag}, {@link SelectTag}, {@link TextareaTag}を保持することができます。
42   * </p>
43   * 
44   * @author agata
45   * @author baba
46   * @since 1.0.0
47   */
48  public class FormTag extends BodyTagSupport implements DynamicAttributes,
49  		ParamParent {
50  
51  	/** シリアルバージョン UID */
52  	private static final long serialVersionUID = 1L;
53  
54  	/** DynamicAttributes */
55  	private final Map<String, Object> attrs = new HashMap<String, Object>();
56  
57  	/** フォームのバインディング対象のBean。 */
58  	private Object value;
59  
60  	/** 出力する URL を {@link HttpServletResponse#encodeURL(String)} でエンコードするか。 */
61  	private boolean encodeURL = true;
62  
63  	/** リンク用の補助クラス。 */
64  	private final LinkSupport linkSupport = new LinkSupport();
65  
66  	/** フォームオブジェクトのラッパー。 */
67  	private FormWrapper formWrapper;
68  
69  	/**
70  	 * {@inheritDoc} DynamicAttributeをセットします。
71  	 */
72  	public void setDynamicAttribute(final String uri, final String localName,
73  			final Object value) throws JspException {
74  		this.attrs.put(localName, value);
75  	}
76  
77  	/**
78  	 * DynamicAttributeを取得します。
79  	 * 
80  	 * @return DynamicAttribute
81  	 */
82  	protected Map<String, Object> getDynamicAttribute() {
83  		return this.attrs;
84  	}
85  
86  	/**
87  	 * フォームのバインディング対象のBeanをセットします。
88  	 * 
89  	 * @param value
90  	 *            フォームのバインディング対象のBean
91  	 */
92  	public void setValue(final Object value) {
93  		this.value = value;
94  	}
95  
96  	/**
97  	 * アクションクラスを設定します。
98  	 * 
99  	 * @param actionClass
100 	 *            アクションクラス
101 	 */
102 	public void setActionClass(final String actionClass) {
103 		linkSupport.setActionClassName(actionClass);
104 	}
105 
106 	/**
107 	 * アクションメソッドを設定します。
108 	 * 
109 	 * @param actionMethod
110 	 *            アクションメソッド
111 	 */
112 	public void setActionMethod(final String actionMethod) {
113 		linkSupport.setActionMethodName(actionMethod);
114 	}
115 
116 	/**
117 	 * 出力する URL を {@link HttpServletResponse#encodeURL(String)} でエンコードするかを設定します。
118 	 * 
119 	 * @param encodeURL
120 	 *            出力する URL を {@link HttpServletResponse#encodeURL(String)}
121 	 *            でエンコードする場合は <code>true</code>、そうでない場合は <code>false</code>
122 	 */
123 	public void setEncodeURL(final boolean encodeURL) {
124 		this.encodeURL = encodeURL;
125 	}
126 
127 	/**
128 	 * リクエストパラメータを追加します。
129 	 * 
130 	 * @param name
131 	 *            パラメータ名
132 	 * @param value
133 	 *            値
134 	 */
135 	public void addParameter(final String name, final String value) {
136 		linkSupport.addParameter(name, value);
137 	}
138 
139 	/**
140 	 * {@inheritDoc}
141 	 */
142 	@Override
143 	public int doStartTag() throws JspException {
144 		final S2Container container = SingletonS2ContainerFactory
145 				.getContainer();
146 		final FormWrapperFactory formWrapperFactory = (FormWrapperFactory) container
147 				.getComponent(FormWrapperFactory.class);
148 		this.formWrapper = formWrapperFactory.create(this.value);
149 		return EVAL_BODY_BUFFERED;
150 	}
151 
152 	/**
153 	 * {@inheritDoc}
154 	 */
155 	@Override
156 	public int doEndTag() throws JspException {
157 		final String contextPath = (String) pageContext.getAttribute(
158 				ATTR_CONTEXT_PATH, PageContext.REQUEST_SCOPE);
159 		if (linkSupport.isLinkable()) {
160 			final String url = contextPath + linkSupport.getPath();
161 			attrs.put("action", url);
162 		}
163 
164 		if (encodeURL && attrs.containsKey("action")) {
165 			final String url = (String) attrs.get("action");
166 			final HttpServletResponse response = (HttpServletResponse) pageContext
167 					.getResponse();
168 			final String encodedUrl = response.encodeURL(url);
169 			attrs.put("action", encodedUrl);
170 		}
171 
172 		final JspWriter out = pageContext.getOut();
173 		try {
174 			out.write("<form ");
175 			out.write(toAttr(getDynamicAttribute()));
176 			out.write(">");
177 			final BodyContent bodyContent = getBodyContent();
178 			if (bodyContent != null) {
179 				bodyContent.writeOut(out);
180 			}
181 			out.write("</form>");
182 		} catch (final IOException e) {
183 			throw new JspException(e);
184 		}
185 		reset();
186 		return EVAL_PAGE;
187 	}
188 
189 	/**
190 	 * このタグをリセットします。
191 	 */
192 	private void reset() {
193 		linkSupport.clear();
194 		attrs.clear();
195 		value = null;
196 		formWrapper = null;
197 	}
198 
199 	/**
200 	 * フォームへ出力する値を取得します。
201 	 * 
202 	 * @param name
203 	 *            フィールド名
204 	 * @return フォームへ出力する値
205 	 * @since 1.1.0
206 	 */
207 	public String[] getValues(final String name) {
208 		return formWrapper.getValues(name);
209 	}
210 
211 }