Clover coverage report - brownies library - 1.0-beta-1 Coverage timestamp: 月 8 16 2004 17:14:42 GMT+09:00 FRAMES NO FRAMES |
file stats: | LOC: | 316 |  | Methods: | 17
| NCLOC: | 192 |  | Classes: | 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
Source file | Conditionals | Statements | Methods | TOTAL
ClassUtils.java | 20.2% | 26.6% | 47.1% | 25.8% |

1 |  |
     /*
2 |  |
      * Joey and its relative products are published under the terms
3 |  |
      * of the Apache Software License.
4 |  |
      */
5 |  |
     package org.asyrinx.brownie.core.lang;
6 |  |
7 |  |
     import java.lang.reflect.Constructor;
8 |  |
     import java.lang.reflect.InvocationTargetException;
9 |  |
     import java.lang.reflect.Modifier;
10 |  |
     import java.util.ArrayList;
11 |  |
     import java.util.List;
12 |  |
13 |  |
     /**
14 |  |
      *
15 |  |
      * クラスに関するユーティリティです。 <br>
16 |  |
      * クラス名を指定した生成、基底クラスのチェック付の生成などが 主な責務です。 <br>
17 |  |
      * インスタンス生成のメソッドnewObjectのほとんどは、引数にbaseClassという
18 |  |
      * Class変数を持ち、この引数によって生成するインスタンスのクラスが
19 |  |
      * 意図しているクラス(あるいはインタフェース)を継承(実装)するものなのかをチェックします。 <br>
20 |  |
      * これらのメソッドは例外InstantiationExceptionをthrowsしています。 これは以下の場合にthrowされます。 <br>
21 |  |
      * ・引数baseClassによるチェックがパスしなかった。 <br>
22 |  |
      * ・クラス名が指定されていない。 <br>
23 |  |
      * ・クラスが見つからない。 <br>
24 |  |
      * ・コンストラクタが見つからない。 <br>
25 |  |
      * ・コンストラクタの引数が異なる。 <br>
26 |  |
      * ・クラスへのアクセス権に問題がある。 <br>
27 |  |
      * ・その他インスタンス生成の例外が発生した場合。 <br>
28 |  |
      * <br>
29 |  |
      *
30 |  |
      * @author Akima
31 |  |
      */
32 |  |
     public class ClassUtils {
33 |  |
34 |  |
         public static final char PACKAGE_DELIM_CHAR = '.';
35 |  |
36 |  |
         public static final String PACKAGE_DELIM = ".";
37 |  |
38 |  |
         /**
39 |  |
          * クラス名によって指定されたクラスのインスタンスを生成します。 <br>
40 |  |
          *
41 |  |
          * @param className
42 |  |
          *            生成されるクラスの名前
43 |  |
          * @param classLoader
44 |  |
          *            クラスを名前で検索する際のクラスローダ
45 |  |
          *            nullを指定した場合には、カレントスレッドのコンテキストクラスローダが使用されます。
46 |  |
          * @param baseClass
47 |  |
          *            生成されるクラスの基底クラス nullを指定した場合には、Objectクラスのclass変数が使用されます。
48 |  |
          * @return 生成されたインスタンス
49 |  |
          * @throws InstantiationException
50 |  |
          */
51 | 0 |
         public static Object newObject(String className, ClassLoader classLoader,
52 |  |
                 Class baseClass) throws InstantiationException {
53 | 0 |
             if (classLoader == null)
54 | 0 |
                 classLoader = Thread.currentThread().getContextClassLoader();
55 | 0 |
             if (className == null)
56 | 0 |
                 throw new InstantiationException("className is null !");
57 | 0 |
             try {
58 | 0 |
                 Class resultClass = classLoader.loadClass(className);
59 | 0 |
                 return newObject(resultClass, baseClass);
60 |  |
             } catch (ClassNotFoundException e) {
61 | 0 |
                 throw new InstantiationException(e.toString());
62 |  |
             }
63 |  |
         }
64 |  |
65 |  |
         /**
66 |  |
          * クラス名によって指定されたクラスのインスタンスを生成します。 <br>
67 |  |
          *
68 |  |
          * @param className
69 |  |
          *            生成されるクラスの名前
70 |  |
          * @param baseClass
71 |  |
          *            生成されるクラスの基底クラス nullを指定した場合には、Objectクラスのclass変数が使用されます。
72 |  |
          * @return 生成されたインスタンス
73 |  |
          * @throws InstantiationException
74 |  |
          */
75 | 3 |
         public static Object newObject(String className, Class baseClass)
76 |  |
                 throws InstantiationException {
77 | 3 |
             if (className == null)
78 | 0 |
                 throw new InstantiationException("className is null !");
79 | 3 |
             try {
80 | 3 |
                 Class resultClass = Class.forName(className);
81 | 3 |
                 return newObject(resultClass, baseClass);
82 |  |
             } catch (ClassNotFoundException e) {
83 | 0 |
                 throw new InstantiationException(e.toString());
84 |  |
             }
85 |  |
         }
86 |  |
87 |  |
         /**
88 |  |
          * 指定されたクラスのインスタンスを生成します。 <br>
89 |  |
          *
90 |  |
          * @param instanciateClass
91 |  |
          *            生成されるクラス
92 |  |
          * @param baseClass
93 |  |
          *            生成されるクラスの基底クラス nullを指定した場合には、Objectクラスのclass変数が使用されます。
94 |  |
          * @return 生成されたインスタンス
95 |  |
          * @throws InstantiationException
96 |  |
          */
97 | 3 |
         public static Object newObject(Class instanciateClass, Class baseClass)
98 |  |
                 throws InstantiationException {
99 | 3 |
             checkByBaseClass(instanciateClass, baseClass);
100 | 3 |
             try {
101 | 3 |
                 return instanciateClass.newInstance();
102 |  |
             } catch (IllegalAccessException e) {
103 | 0 |
                 throw new InstantiationException(e.toString());
104 |  |
             }
105 |  |
         }
106 |  |
107 |  |
         /**
108 |  |
          * コンストラクタを検索しインスタンスを生成します。 <br>
109 |  |
          *
110 |  |
          * @param instanciateClass
111 |  |
          *            生成されるインスタンスのクラス。
112 |  |
          * @param baseClass
113 |  |
          *            生成されるインスタンスのクラスの基底クラス nullを指定した場合には、Objectクラスのclass変数が使用されます。
114 |  |
          * @param params
115 |  |
          *            コンストラクタに渡される引数。
116 |  |
          * @return 生成されたインスタンス
117 |  |
          * @throws InstantiationException
118 |  |
          */
119 | 1 |
         public static Object newObject(Class instanciateClass, Class baseClass,
120 |  |
                 Object[] params) throws InstantiationException {
121 | 1 |
             checkByBaseClass(instanciateClass, baseClass);
122 | 1 |
             Constructor constructor = findConstructor(instanciateClass, params);
123 | 1 |
             if (constructor == null)
124 | 0 |
                 throw new InstantiationException("該当するコンストラクタが見つかりませんでした");
125 | 1 |
             try {
126 | 1 |
                 return constructor.newInstance(params);
127 |  |
             } catch (InstantiationException e) {
128 | 0 |
                 throw new InstantiationException(e.toString());
129 |  |
             } catch (IllegalAccessException e) {
130 | 0 |
                 throw new InstantiationException(e.toString());
131 |  |
             } catch (InvocationTargetException e) {
132 | 0 |
                 throw new InstantiationException(e.toString());
133 |  |
             }
134 |  |
         }
135 |  |
136 |  |
         /**
137 |  |
          * コンストラクタを検索しインスタンスを生成します。 <br>
138 |  |
          *
139 |  |
          * @param className
140 |  |
          *            生成されるクラスの名前
141 |  |
          * @param classLoader
142 |  |
          *            クラスを名前で検索する際のクラスローダ
143 |  |
          *            nullを指定した場合には、カレントスレッドのコンテキストクラスローダが使用されます。
144 |  |
          * @param baseClass
145 |  |
          *            生成されるインスタンスのクラスの基底クラス nullを指定した場合には、Objectクラスのclass変数が使用されます。
146 |  |
          * @param params
147 |  |
          *            コンストラクタに渡される引数。
148 |  |
          * @return 生成されたインスタンス
149 |  |
          * @throws InstantiationException
150 |  |
          */
151 | 0 |
         public static Object newObject(String className, ClassLoader classLoader,
152 |  |
                 Class baseClass, Object[] params) throws InstantiationException {
153 | 0 |
             if (classLoader == null)
154 | 0 |
                 classLoader = Thread.currentThread().getContextClassLoader();
155 | 0 |
             if (className == null)
156 | 0 |
                 throw new InstantiationException("className is null !");
157 | 0 |
             try {
158 | 0 |
                 Class resultClass = classLoader.loadClass(className);
159 | 0 |
                 return newObject(resultClass, baseClass, params);
160 |  |
             } catch (ClassNotFoundException e) {
161 | 0 |
                 throw new InstantiationException(e.toString());
162 |  |
             }
163 |  |
         }
164 |  |
165 |  |
         /**
166 |  |
          * クラスと引数からコンストラクタを検索します。 <br>
167 |  |
          */
168 | 1 |
         public static Constructor findConstructor(Class targetClass, Object[] params) {
169 | 1 |
             Constructor[] constructors = targetClass.getConstructors();
170 | 1 |
             for (int i = 0; i < constructors.length; i++) {
171 | 1 |
                 if (matchTypes(params, constructors[i].getParameterTypes()))
172 | 1 |
                     return constructors[i];
173 |  |
             }
174 | 0 |
             return null;
175 |  |
         }
176 |  |
177 |  |
         /**
178 |  |
          * 引数valuesの各要素が、引数valueTypesの各要素(Classクラスのインスタンス)の
179 |  |
          * インスタンスとして対応するるかどうかを判断します。 <br>
180 |  |
          *
181 |  |
          * @return 全てのvalueのクラスがvalueTypesと合致すればtrue、一つでも合致しないものがあればfalse。
182 |  |
          */
183 | 1 |
         public static boolean matchTypes(Object[] values, Class[] valueTypes) {
184 | 1 |
             if (values == null)
185 | 0 |
                 return (valueTypes == null) || (valueTypes.length == 0);
186 | 1 |
             if (valueTypes == null)
187 | 0 |
                 return false;
188 | 1 |
             if (values.length != valueTypes.length)
189 | 0 |
                 return false;
190 | 1 |
             for (int i = 0; i < values.length; i++) {
191 | 1 |
                 if (!valueTypes[i].isInstance(values[i]))
192 | 0 |
                     return false;
193 |  |
             }
194 | 1 |
             return true;
195 |  |
         }
196 |  |
197 | 0 |
         public static List modifierToString(int value) {
198 | 0 |
             List result = new ArrayList();
199 | 0 |
             if (Modifier.isAbstract(value))
200 | 0 |
                 result.add("abstract");
201 | 0 |
             if (Modifier.isFinal(value))
202 | 0 |
                 result.add("final");
203 | 0 |
             if (Modifier.isInterface(value))
204 | 0 |
                 result.add("interface");
205 | 0 |
             if (Modifier.isNative(value))
206 | 0 |
                 result.add("native");
207 | 0 |
             if (Modifier.isPrivate(value))
208 | 0 |
                 result.add("private");
209 | 0 |
             if (Modifier.isProtected(value))
210 | 0 |
                 result.add("protected");
211 | 0 |
             if (Modifier.isPublic(value))
212 | 0 |
                 result.add("public");
213 | 0 |
             if (Modifier.isStatic(value))
214 | 0 |
                 result.add("static");
215 | 0 |
             if (Modifier.isStrict(value))
216 | 0 |
                 result.add("strict");
217 | 0 |
             if (Modifier.isSynchronized(value))
218 | 0 |
                 result.add("synchronized");
219 | 0 |
             if (Modifier.isTransient(value))
220 | 0 |
                 result.add("transient");
221 | 0 |
             if (Modifier.isVolatile(value))
222 | 0 |
                 result.add("volatile");
223 | 0 |
             return result;
224 |  |
         }
225 |  |
226 | 4 |
         static private void checkByBaseClass(Class targetClass, Class baseClass)
227 |  |
                 throws InstantiationException {
228 | 4 |
             if (baseClass == null)
229 | 4 |
                 baseClass = Object.class;
230 | 4 |
             if (!baseClass.isAssignableFrom(targetClass))
231 | 0 |
                 throw new InstantiationException(targetClass.getName() + "クラスは"
232 |  |
                         + baseClass.getName() + "クラスと互換性がありません");
233 |  |
         }
234 |  |
235 |  |
         /**
236 |  |
          * 指定したtargetクラスが、classNameで表されるクラス名のクラスかどうかを返す。
237 |  |
          * もし、クラス名でなかった場合はtargetクラスのスーパークラスのクラス名と比較する。
238 |  |
          *
239 |  |
          * @param target
240 |  |
          *            対象となるClassクラスのインスタンス
241 |  |
          * @param className
242 |  |
          *            照合するクラス名。
243 |  |
          * @return 継承ツリーをさかのぼった結果、クラス名がclassNameと照合するクラスがあればtrueなければfalse
244 |  |
          */
245 | 0 |
         static public boolean isAssignableFrom(Class target, final String className) {
246 | 0 |
             if (className == null)
247 | 0 |
                 return false;
248 | 0 |
             if (target == null)
249 | 0 |
                 return false;
250 | 0 |
             if (className.equals(target.getName()))
251 | 0 |
                 return true;
252 | 0 |
             Class[] intf = target.getInterfaces();
253 | 0 |
             for (int idx = 0; idx < intf.length; idx++) {
254 | 0 |
                 if (isAssignableFrom(intf[idx], className))
255 | 0 |
                     return true;
256 |  |
             }
257 | 0 |
             return isAssignableFrom(target.getSuperclass(), className);
258 |  |
         }
259 |  |
260 | 0 |
         static public void showClassLoaders() {
261 | 0 |
             showClassLoaders(Thread.currentThread().getContextClassLoader());
262 |  |
         }
263 |  |
264 | 0 |
         static public void showClassLoaders(Class clazz) {
265 | 0 |
             showClassLoaders(clazz.getClassLoader());
266 |  |
         }
267 |  |
268 | 0 |
         static public void showClassLoaders(ClassLoader loader) {
269 | 0 |
             if (loader == null) {
270 | 0 |
                 return;
271 |  |
             }
272 | 0 |
             int depth = getClassLoaderDepth(loader);
273 | 0 |
             ClassLoader target = loader;
274 | 0 |
             while (target != null) {
275 | 0 |
                 System.out.println(depth + ": " + target);
276 | 0 |
                 depth--;
277 | 0 |
                 target = target.getParent();
278 |  |
             }
279 |  |
         }
280 |  |
281 | 0 |
         public static int getClassLoaderDepth(ClassLoader loader) {
282 | 0 |
             int result = 0;
283 | 0 |
             while (loader != null) {
284 | 0 |
                 result++;
285 | 0 |
                 loader = loader.getParent();
286 |  |
             }
287 | 0 |
             return result;
288 |  |
         }
289 |  |
290 | 0 |
         public static boolean isAncestor(ClassLoader ancestor, ClassLoader target) {
291 | 0 |
             if (target == null && ancestor == null)
292 | 0 |
                 return true;
293 | 0 |
             if (target == null)
294 | 0 |
                 return false;
295 | 0 |
             if (target == ancestor)
296 | 0 |
                 return true;
297 | 0 |
             return isAncestor(ancestor, target.getParent());
298 |  |
         }
299 |  |
300 | 1 |
         public static String toShortClassName(Class class1) {
301 | 1 |
             if (class1 == null)
302 | 1 |
                 return null;
303 | 0 |
             return toShortClassName(class1.getName());
304 |  |
         }
305 |  |
306 | 4 |
         public static String toShortClassName(String className) {
307 | 4 |
             if (StringUtils.isEmpty(className))
308 | 2 |
                 return null;
309 | 2 |
             final List elements = StringUtils.tokenize(className, PACKAGE_DELIM);
310 | 2 |
             if (elements == null)
311 | 0 |
                 return null;
312 | 2 |
             if (elements.isEmpty())
313 | 0 |
                 return null;
314 | 2 |
             return String.valueOf(elements.get(elements.size() - 1));
315 |  |
         }
316 |  |
     }