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.internal.util;
    17
    18  import java.lang.reflect.Method;
    19
    20  import org.seasar.cubby.action.Accept;
    21  import org.seasar.cubby.action.OnSubmit;
    22  import org.seasar.cubby.action.Path;
    23  import org.seasar.cubby.action.RequestMethod;
    24
    25  /**
    26   * アクションのメタ情報を扱うためのユーティリティクラスです。
    27   *
    28   * @author baba
    29   */
    30  public class MetaUtils {
    31
    32  	/** インデックスのメソッド名。 */
    33  	private static final String INDEX_METHOD_NAME = "index";
    34
    35  	/** デフォルトの{@link Accept}アノテーション。 */
    36  	private static final Accept DEFAULT_ACCEPT_ANNOTATION;
    37  	static {
    38  		@Accept
    39  		class AcceptDummy {
    40  		}
    41  		DEFAULT_ACCEPT_ANNOTATION = AcceptDummy.class
    42  				.getAnnotation(Accept.class);
    43  	}
    44
    45  	/**
    46  	 * 指定されたアクションクラスに対応するディレクトリを取得します。
    47  	 *
    48  	 * @param actionClass
    49  	 *            アクションクラス
    50  	 * @return アクションクラスに対応するディレクトリ
    51  	 */
    52  	public static String getActionDirectory(final Class<?> actionClass) {
    53  		final String actionName;
    54  		final Path path = actionClass.getAnnotation(Path.class);
    55  		if (path != null && !StringUtils.isEmpty(path.value())) {
    56  			actionName = path.value();
    57  		} else {
    58  			final String name = left(actionClass.getSimpleName(), "$");
    59  			actionName = toFirstLower(name.replaceAll(
    60  					"(.*[.])*([^.]+)(Action$)", "$2"));
    61  		}
    62  		return actionName;
    63  	}
    64
    65  	/**
    66  	 * 指定された文字列をセパレータで区切った左側の文字列を返します。
    67  	 *
    68  	 * @param text
    69  	 *            文字列
    70  	 * @param sep
    71  	 *            セパレータ
    72  	 * @return セパレータで区切った左側の文字列
    73  	 */
    74  	private static String left(final String text, final String sep) {
    75  		final int pos = text.indexOf(sep);
    76  		if (pos != -1) {
    77  			return text.substring(0, pos);
    78  		}
    79  		return text;
    80  	}
    81
    82  	/**
    83  	 * 指定された文字列の先頭1文字を小文字に変換します。
    84  	 *
    85  	 * @param text
    86  	 *            変換する文字列
    87  	 * @return 先頭1文字を小文字にした文字列
    88  	 */
    89  	private static String toFirstLower(final String text) {
    90  		if (StringUtils.isEmpty(text)) {
    91  			throw new IllegalArgumentException("text is empty.");
    92  		}
    93  		final StringBuilder sb = new StringBuilder();
    94  		sb.append(text.substring(0, 1).toLowerCase());
    95  		if (text.length() > 1) {
    96  			sb.append(text.substring(1));
    97  		}
    98  		return sb.toString();
    99  	}
    100
    101 	/**
    102 	 * 指定されたアクションメソッドのパスを取得します。
    103 	 *
    104 	 * @param actionClass
    105 	 *            アクションクラス
    106 	 * @param method
    107 	 *            アクションメソッド
    108 	 * @return アクションメソッドのパス
    109 	 */
    110 	public static String getActionPath(final Class<?> actionClass,
    111 			final Method method) {
    112 		final String path;
    113 		final String actionMethodName = getActionMethodName(method);
    114 		if (actionMethodName.startsWith("/")) {
    115 			path = actionMethodName;
    116 		} else {
    117 			final String actionDirectory = getActionDirectory(actionClass);
    118 			if ("/".equals(actionDirectory)) {
    119 				path = "/" + actionMethodName;
    120 			} else {
    121 				path = "/" + actionDirectory + "/" + actionMethodName;
    122 			}
    123 		}
    124 		return path;
    125 	}
    126
    127 	/**
    128 	 * 指定されたアクションメソッドのアクションメソッド名を取得します。
    129 	 *
    130 	 * @param method
    131 	 *            アクションメソッド
    132 	 * @return アクションメソッド名
    133 	 */
    134 	private static String getActionMethodName(final Method method) {
    135 		final String actionName;
    136 		final Path path = method.getAnnotation(Path.class);
    137 		if (path != null && !StringUtils.isEmpty(path.value())) {
    138 			actionName = path.value();
    139 		} else {
    140 			final String methodName = method.getName();
    141 			if (INDEX_METHOD_NAME.equals(methodName)) {
    142 				actionName = "";
    143 			} else {
    144 				actionName = methodName;
    145 			}
    146 		}
    147 		return actionName;
    148 	}
    149
    150 	/**
    151 	 * 指定されたアクションメソッドが受付可能な要求メソッドを取得します。
    152 	 *
    153 	 * @param actionClass
    154 	 *            アクションクラス
    155 	 * @param method
    156 	 *            アクションメソッド
    157 	 * @return 受付可能な要求メソッド
    158 	 */
    159 	public static RequestMethod[] getAcceptableRequestMethods(
    160 			final Class<?> actionClass, final Method method) {
    161 		final Accept accept;
    162 		if (method.isAnnotationPresent(Accept.class)) {
    163 			accept = method.getAnnotation(Accept.class);
    164 		} else if (actionClass.isAnnotationPresent(Accept.class)) {
    165 			accept = actionClass.getAnnotation(Accept.class);
    166 		} else {
    167 			accept = DEFAULT_ACCEPT_ANNOTATION;
    168 		}
    169 		return accept.value();
    170 	}
    171
    172 	/**
    173 	 * アクションメソッドの{@link Path}アノテーションから優先度を取得します。
    174 	 *
    175 	 * @param method
    176 	 *            アクションメソッド
    177 	 * @return 優先度。メソッドに{@link Path}アノテーションが設定されていない場合{@link Integer#MAX_VALUE}
    178 	 */
    179 	public static int getPriority(final Method method) {
    180 		final Path path = method.getAnnotation(Path.class);
    181 		return path != null ? path.priority() : Integer.MAX_VALUE;
    182 	}
    183
    184 	/**
    185 	 * 指定されたアクションメソッドを使用することを判断するためのパラメータ名を取得します。
    186 	 * <p>
    187 	 * パラメータ名によらずに実行する場合は <code>null</code> を返します。
    188 	 * </p>
    189 	 *
    190 	 * @param method
    191 	 *            アクションメソッド
    192 	 * @return パラメータ名
    193 	 */
    194 	public static String getOnSubmit(final Method method) {
    195 		final OnSubmit onSubmit = method.getAnnotation(OnSubmit.class);
    196 		final String parameterName;
    197 		if (onSubmit == null) {
    198 			parameterName = null;
    199 		} else {
    200 			parameterName = onSubmit.value();
    201 		}
    202 		return parameterName;
    203 	}
    204
    205 }