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.tags.TagUtils.getContextPath;
    19  import static org.seasar.cubby.tags.TagUtils.toAttr;
    20
    21  import java.io.IOException;
    22  import java.net.MalformedURLException;
    23  import java.util.HashMap;
    24  import java.util.Map;
    25
    26  import javax.servlet.http.HttpServletRequest;
    27  import javax.servlet.http.HttpServletResponse;
    28  import javax.servlet.jsp.JspException;
    29  import javax.servlet.jsp.JspWriter;
    30  import javax.servlet.jsp.tagext.BodyContent;
    31  import javax.servlet.jsp.tagext.BodyTagSupport;
    32  import javax.servlet.jsp.tagext.DynamicAttributes;
    33
    34  import org.seasar.cubby.util.LinkBuilder;
    35
    36  /**
    37   * 指定されたアクションクラス、アクションメソッドへリンクする URL を特定の属性にもつタグを出力するカスタムタグです。
    38   *
    39   * @author baba
    40   */
    41  public class LinkTag extends BodyTagSupport implements DynamicAttributes,
    42  		ParamParent {
    43
    44  	/** シリアルバージョン UID */
    45  	private static final long serialVersionUID = 1L;
    46
    47  	/** DynamicAttributes */
    48  	private final Map<String, Object> dynamicAttributes = new HashMap<String, Object>();
    49
    50  	/** リンクの補助クラス。 */
    51  	private final LinkSupport linkSupport = new LinkSupport();
    52
    53  	/** リンクビルダ。 */
    54  	private final LinkBuilder linkBuilder = new LinkBuilder();
    55
    56  	/** 出力するタグ。 */
    57  	private String tag;
    58
    59  	/** リンクする URL を出力する属性。 */
    60  	private String attr;
    61
    62  	/** 出力する URL を {@link HttpServletResponse#encodeURL(String)} でエンコードするか。 */
    63  	private boolean encodeURL = true;
    64
    65  	/**
    66  	 * {@inheritDoc} DynamicAttributeをセットします。
    67  	 */
    68  	public void setDynamicAttribute(final String uri, final String localName,
    69  			final Object value) throws JspException {
    70  		this.dynamicAttributes.put(localName, value);
    71  	}
    72
    73  	/**
    74  	 * 出力するタグを設定します。
    75  	 *
    76  	 * @param tag
    77  	 *            出力するタグ
    78  	 */
    79  	public void setTag(final String tag) {
    80  		this.tag = tag;
    81  	}
    82
    83  	/**
    84  	 * リンクする URL を出力する属性を設定します。
    85  	 *
    86  	 * @param attr
    87  	 *            リンクする URL を出力する属性
    88  	 */
    89  	public void setAttr(final String attr) {
    90  		this.attr = attr;
    91  	}
    92
    93  	/**
    94  	 * アクションクラスを設定します。
    95  	 *
    96  	 * @param actionClass
    97  	 *            アクションクラス
    98  	 */
    99  	public void setActionClass(final String actionClass) {
    100 		linkSupport.setActionClassName(actionClass);
    101 	}
    102
    103 	/**
    104 	 * アクションメソッドを設定します。
    105 	 *
    106 	 * @param actionMethod
    107 	 *            アクションメソッド
    108 	 */
    109 	public void setActionMethod(final String actionMethod) {
    110 		linkSupport.setActionMethodName(actionMethod);
    111 	}
    112
    113 	/**
    114 	 * 出力する URL を {@link HttpServletResponse#encodeURL(String)} でエンコードするかを設定します。
    115 	 *
    116 	 * @param encodeURL
    117 	 *            出力する URL を {@link HttpServletResponse#encodeURL(String)}
    118 	 *            でエンコードする場合は <code>true</code>、そうでない場合は <code>false</code>
    119 	 */
    120 	public void setEncodeURL(final boolean encodeURL) {
    121 		this.encodeURL = encodeURL;
    122 	}
    123
    124 	/**
    125 	 * 出力する URL のプロトコルを設定します。
    126 	 *
    127 	 * @param protocol
    128 	 *            出力する URL のプロトコル
    129 	 */
    130 	public void setProtocol(final String protocol) {
    131 		linkBuilder.setProtocol(protocol);
    132 	}
    133
    134 	/**
    135 	 * 出力する URL のポートを設定します。
    136 	 *
    137 	 * @param port
    138 	 *            出力する URL のポート
    139 	 */
    140 	public void setPort(final int port) {
    141 		linkBuilder.setPort(port);
    142 	}
    143
    144 	/**
    145 	 * 要求パラメータを追加します。
    146 	 *
    147 	 * @param name
    148 	 *            パラメータ名
    149 	 * @param value
    150 	 *            値
    151 	 */
    152 	public void addParameter(final String name, final String value) {
    153 		linkSupport.addParameter(name, value);
    154 	}
    155
    156 	/**
    157 	 * {@inheritDoc}
    158 	 */
    159 	@Override
    160 	public int doStartTag() throws JspException {
    161 		return EVAL_BODY_BUFFERED;
    162 	}
    163
    164 	/**
    165 	 * {@inheritDoc}
    166 	 */
    167 	@Override
    168 	public int doEndTag() throws JspException {
    169 		final String contextPath = getContextPath(pageContext);
    170 		final String actionPath;
    171 		final HttpServletRequest request = (HttpServletRequest) pageContext
    172 				.getRequest();
    173 		final String characterEncoding = request.getCharacterEncoding();
    174 		if (encodeURL) {
    175 			final HttpServletResponse response = (HttpServletResponse) pageContext
    176 					.getResponse();
    177 			actionPath = response.encodeURL(contextPath
    178 					+ linkSupport.getPath(characterEncoding));
    179 		} else {
    180 			actionPath = contextPath + linkSupport.getPath(characterEncoding);
    181 		}
    182
    183 		final String url;
    184 		try {
    185 			url = linkBuilder.file(actionPath).toLink(request);
    186 		} catch (final MalformedURLException e) {
    187 			throw new JspException(e);
    188 		}
    189
    190 		try {
    191 			final JspWriter out = pageContext.getOut();
    192 			if (tag == null) {
    193 				out.write(url);
    194 				final BodyContent bodyContent = getBodyContent();
    195 				if (bodyContent != null) {
    196 					bodyContent.writeOut(out);
    197 				}
    198 			} else {
    199 				dynamicAttributes.put(attr, url);
    200 				out.write("<");
    201 				out.write(tag);
    202 				out.write(" ");
    203 				out.write(toAttr(dynamicAttributes));
    204 				out.write(">");
    205 				final BodyContent bodyContent = getBodyContent();
    206 				if (bodyContent != null) {
    207 					bodyContent.writeOut(out);
    208 				}
    209 				out.write("</");
    210 				out.write(tag);
    211 				out.write(">");
    212 			}
    213 		} catch (final IOException e) {
    214 			throw new JspException(e);
    215 		}
    216 		reset();
    217 		return EVAL_PAGE;
    218 	}
    219
    220 	/**
    221 	 * このタグをリセットします。
    222 	 */
    223 	private void reset() {
    224 		linkSupport.clear();
    225 		linkBuilder.clear();
    226 		dynamicAttributes.clear();
    227 		tag = null;
    228 		attr = null;
    229 		encodeURL = true;
    230 	}
    231
    232 }