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  /**
34   * 指定されたアクションクラス、アクションメソッドへリンクする URL を特定の属性にもつタグを出力するカスタムタグです。
35   * 
36   * @author baba
37   * @since 1.1.0
38   */
39  public class LinkTag extends BodyTagSupport implements DynamicAttributes,
40  		ParamParent {
41  
42  	/** シリアルバージョン UID */
43  	private static final long serialVersionUID = 1L;
44  
45  	/** DynamicAttributes */
46  	private final Map<String, Object> attrs = new HashMap<String, Object>();
47  
48  	/** リンクの補助クラス。 */
49  	private final LinkSupport linkSupport = new LinkSupport();
50  
51  	/** 出力するタグ。 */
52  	private String tag;
53  
54  	/** リンクする URL を出力する属性。 */
55  	private String attr;
56  
57  	/** 出力する URL を {@link HttpServletResponse#encodeURL(String)} でエンコードするか。 */
58  	private boolean encodeURL = true;
59  
60  	/**
61  	 * {@inheritDoc} DynamicAttributeをセットします。
62  	 */
63  	public void setDynamicAttribute(final String uri, final String localName,
64  			final Object value) throws JspException {
65  		this.attrs.put(localName, value);
66  	}
67  
68  	/**
69  	 * 出力するタグを設定します。
70  	 * 
71  	 * @param tag
72  	 *            出力するタグ
73  	 */
74  	public void setTag(final String tag) {
75  		this.tag = tag;
76  	}
77  
78  	/**
79  	 * リンクする URL を出力する属性を設定します。
80  	 * 
81  	 * @param attr
82  	 *            リンクする URL を出力する属性
83  	 */
84  	public void setAttr(final String attr) {
85  		this.attr = attr;
86  	}
87  
88  	/**
89  	 * アクションクラスを設定します。
90  	 * 
91  	 * @param actionClass
92  	 *            アクションクラス
93  	 */
94  	public void setActionClass(final String actionClass) {
95  		linkSupport.setActionClassName(actionClass);
96  	}
97  
98  	/**
99  	 * アクションメソッドを設定します。
100 	 * 
101 	 * @param actionMethod
102 	 *            アクションメソッド
103 	 */
104 	public void setActionMethod(final String actionMethod) {
105 		linkSupport.setActionMethodName(actionMethod);
106 	}
107 
108 	/**
109 	 * 出力する URL を {@link HttpServletResponse#encodeURL(String)} でエンコードするかを設定します。
110 	 * 
111 	 * @param encodeURL
112 	 *            出力する URL を {@link HttpServletResponse#encodeURL(String)}
113 	 *            でエンコードする場合は <code>true</code>、そうでない場合は <code>false</code>
114 	 */
115 	public void setEncodeURL(final boolean encodeURL) {
116 		this.encodeURL = encodeURL;
117 	}
118 
119 	/**
120 	 * リクエストパラメータを追加します。
121 	 * 
122 	 * @param name
123 	 *            パラメータ名
124 	 * @param value
125 	 *            値
126 	 */
127 	public void addParameter(final String name, final String value) {
128 		linkSupport.addParameter(name, value);
129 	}
130 
131 	/**
132 	 * {@inheritDoc}
133 	 */
134 	@Override
135 	public int doStartTag() throws JspException {
136 		return EVAL_BODY_BUFFERED;
137 	}
138 
139 	/**
140 	 * {@inheritDoc}
141 	 */
142 	@Override
143 	public int doEndTag() throws JspException {
144 		final String contextPath = (String) pageContext.getAttribute(
145 				ATTR_CONTEXT_PATH, PageContext.REQUEST_SCOPE);
146 		final String url;
147 		final String characterEncoding = pageContext.getRequest()
148 				.getCharacterEncoding();
149 		if (encodeURL) {
150 			final HttpServletResponse response = HttpServletResponse.class
151 					.cast(pageContext.getResponse());
152 			url = response.encodeURL(contextPath
153 					+ linkSupport.getPath(characterEncoding));
154 		} else {
155 			url = contextPath + linkSupport.getPath(characterEncoding);
156 		}
157 
158 		try {
159 			final JspWriter out = pageContext.getOut();
160 			if (tag == null) {
161 				out.write(url);
162 				final BodyContent bodyContent = getBodyContent();
163 				if (bodyContent != null) {
164 					bodyContent.writeOut(out);
165 				}
166 			} else {
167 				attrs.put(attr, url);
168 				out.write("<");
169 				out.write(tag);
170 				out.write(" ");
171 				out.write(toAttr(attrs));
172 				out.write(">");
173 				final BodyContent bodyContent = getBodyContent();
174 				if (bodyContent != null) {
175 					bodyContent.writeOut(out);
176 				}
177 				out.write("</");
178 				out.write(tag);
179 				out.write(">");
180 			}
181 		} catch (final IOException e) {
182 			throw new JspException(e);
183 		}
184 		reset();
185 		return EVAL_PAGE;
186 	}
187 
188 	/**
189 	 * このタグをリセットします。
190 	 */
191 	private void reset() {
192 		linkSupport.clear();
193 		attrs.clear();
194 		tag = null;
195 		attr = null;
196 		encodeURL = true;
197 	}
198 
199 }