##### Coverage Report - org.seasar.cubby.internal.util.MetaUtils

Classes in this File | Line Coverage | Branch Coverage | Complexity
MetaUtils |
89% | 44/49
75% | 21/28
| 3.0;3
MetaUtils$1AcceptDummy |
0% | 0/1
N/A | N/A
| 3.0;3

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 | 0 |
     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 | 0 |
                     class AcceptDummy {
40 |  |
                     }
41 | 1 |
                     DEFAULT_ACCEPT_ANNOTATION = AcceptDummy.class
42 |  |
                                     .getAnnotation(Accept.class);
43 | 1 |
             }
44 |  |
45 |  |
             /**
46 |  |
              * 指定されたアクションクラスに対応するディレクトリを取得します。
47 |  |
              *
48 |  |
              * @param actionClass
49 |  |
              *            アクションクラス
50 |  |
              * @return アクションクラスに対応するディレクトリ
51 |  |
              */
52 |  |
             public static String getActionDirectory(final Class<?> actionClass) {
53 |  |
                     final String actionName;
54 | 304 |
                     final Path path = actionClass.getAnnotation(Path.class);
55 | 304 |
                     if (path != null && !StringUtils.isEmpty(path.value())) {
56 | 129 |
                             actionName = path.value();
57 |  |
                     } else {
58 | 175 |
                             final String name = left(actionClass.getSimpleName(), "$");
59 | 175 |
                             actionName = toFirstLower(name.replaceAll(
60 |  |
                                             "(.*[.])*([^.]+)(Action$)", "$2"));
61 |  |
                     }
62 | 304 |
                     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 | 175 |
                     final int pos = text.indexOf(sep);
76 | 175 |
                     if (pos != -1) {
77 | 0 |
                             return text.substring(0, pos);
78 |  |
                     }
79 | 175 |
                     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 | 175 |
                     if (StringUtils.isEmpty(text)) {
91 | 0 |
                             throw new IllegalArgumentException("text is empty.");
92 |  |
                     }
93 | 175 |
                     final StringBuilder sb = new StringBuilder();
94 | 175 |
                     sb.append(text.substring(0, 1).toLowerCase());
95 | 175 |
                     if (text.length() > 1) {
96 | 175 |
                             sb.append(text.substring(1));
97 |  |
                     }
98 | 175 |
                     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 | 299 |
                     final String actionMethodName = getActionMethodName(method);
114 | 299 |
                     if (actionMethodName.startsWith("/")) {
115 | 5 |
                             path = actionMethodName;
116 |  |
                     } else {
117 | 294 |
                             final String actionDirectory = getActionDirectory(actionClass);
118 | 294 |
                             if ("/".equals(actionDirectory)) {
119 | 49 |
                                     path = "/" + actionMethodName;
120 |  |
                             } else {
121 | 245 |
                                     path = "/" + actionDirectory + "/" + actionMethodName;
122 |  |
                             }
123 |  |
                     }
124 | 299 |
                     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 | 299 |
                     final Path path = method.getAnnotation(Path.class);
137 | 299 |
                     if (path != null && !StringUtils.isEmpty(path.value())) {
138 | 171 |
                             actionName = path.value();
139 |  |
                     } else {
140 | 128 |
                             final String methodName = method.getName();
141 | 128 |
                             if (INDEX_METHOD_NAME.equals(methodName)) {
142 | 49 |
                                     actionName = "";
143 |  |
                             } else {
144 | 79 |
                                     actionName = methodName;
145 |  |
                             }
146 |  |
                     }
147 | 299 |
                     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 | 288 |
                     if (method.isAnnotationPresent(Accept.class)) {
163 | 45 |
                             accept = method.getAnnotation(Accept.class);
164 | 243 |
                     } else if (actionClass.isAnnotationPresent(Accept.class)) {
165 | 0 |
                             accept = actionClass.getAnnotation(Accept.class);
166 |  |
                     } else {
167 | 243 |
                             accept = DEFAULT_ACCEPT_ANNOTATION;
168 |  |
                     }
169 | 288 |
                     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 | 549 |
                     final Path path = method.getAnnotation(Path.class);
181 | 549 |
                     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 | 546 |
                     final OnSubmit onSubmit = method.getAnnotation(OnSubmit.class);
196 |  |
                     final String parameterName;
197 | 546 |
                     if (onSubmit == null) {
198 | 546 |
                             parameterName = null;
199 |  |
                     } else {
200 | 0 |
                             parameterName = onSubmit.value();
201 |  |
                     }
202 | 546 |
                     return parameterName;
203 |  |
             }
204 |  |
205 |  |
     }