001 /*
002 * Java Genetic Algorithm Library (jenetics-1.6.0).
003 * Copyright (c) 2007-2014 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019 */
020 package org.jenetics.internal.util;
021
022 import java.lang.reflect.Method;
023 import java.util.ArrayList;
024 import java.util.Collections;
025 import java.util.Deque;
026 import java.util.LinkedList;
027 import java.util.List;
028
029 import org.jenetics.util.StaticObject;
030
031 /**
032 * Helper methods concerning Java reflection.
033 *
034 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
035 * @version 1.6 — <em>$Date: 2014-02-02 $</em>
036 * @since 1.6
037 */
038 public class reflect extends StaticObject {
039 private reflect() {}
040
041 /**
042 * Return all declared classes of the given class, with arbitrary nested
043 * level.
044 *
045 * @param cls the class for which the declared classes are retrieved.
046 * @return all nested classes
047 */
048 public static List<Class<?>> allDeclaredClasses(final Class<?> cls) {
049 final Deque<Class<?>> stack = new LinkedList<>();
050 stack.addFirst(cls);
051
052 final List<Class<?>> result = new ArrayList<>();
053 while (!stack.isEmpty()) {
054 final Class<?>[] classes = stack.pollFirst().getDeclaredClasses();
055 for (final Class<?> c : classes) {
056 result.add(c);
057 stack.addFirst(c);
058 }
059 }
060
061 return Collections.unmodifiableList(result);
062 }
063
064 /**
065 * Returns a Method object that reflects the specified public member method
066 * of the class or interface represented by this Class object.
067 *
068 * @param type the class for getting the desired method.
069 * @param name the method name
070 * @param parameterTypes the method parameter types.
071 * @return the method, or {@code null} if no such method can be found.
072 */
073 public static Method getMethod(
074 final Class<?> type,
075 final String name,
076 Class<?>[] parameterTypes
077 ) {
078 Method method = null;
079 final Method[] methods = type.getMethods();
080
081 for (int i = 0; i < methods.length && method == null; ++i) {
082 if (name.equals(methods[i].getName()) &&
083 equals(parameterTypes, methods[i].getParameterTypes()))
084 {
085 method = methods[i];
086 }
087 }
088
089 return method;
090 }
091
092 private static boolean equals(final Class<?>[] p1, final Class<?>[] p2) {
093 boolean equals = p1.length == p2.length;
094 for (int i = 0; i < p1.length && equals; ++i) {
095 equals = toClassType(p1[i]) == toClassType(p2[i]);
096 }
097
098 return equals;
099 }
100
101 private static Class<?> toClassType(final Class<?> type) {
102 switch (type.getCanonicalName()) {
103 case "void": return Void.class;
104 case "boolean": return Boolean.class;
105 case "byte": return Byte.class;
106 case "char": return Character.class;
107 case "short": return Short.class;
108 case "int": return Integer.class;
109 case "long": return Long.class;
110 case "float": return Float.class;
111 case "double": return Double.class;
112 default: return type;
113 }
114 }
115
116 /**
117 * Return the class of the given value or the value if it is already from
118 * the type {@code Class}.
119 *
120 * @param value the value to get the class from.
121 * @return the class from the given value, or {@code value} if it is already
122 * a {@code Class}.
123 */
124 public static Class<?> classOf(final Object value) {
125 return value instanceof Class<?> ? (Class<?>)value : value.getClass();
126 }
127
128 }
|