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