001: /*
002: * Spoon - http://spoon.gforge.inria.fr/
003: * Copyright (C) 2006 INRIA Futurs <renaud.pawlak@inria.fr>
004: *
005: * This software is governed by the CeCILL-C License under French law and
006: * abiding by the rules of distribution of free software. You can use, modify
007: * and/or redistribute the software under the terms of the CeCILL-C license as
008: * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
009: *
010: * This program is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
013: *
014: * The fact that you are presently reading this means that you have had
015: * knowledge of the CeCILL-C license and that you accept its terms.
016: */
017:
018: package spoon.support.util;
019:
020: import java.lang.reflect.Field;
021: import java.lang.reflect.InvocationTargetException;
022: import java.lang.reflect.Method;
023: import java.lang.reflect.Modifier;
024: import java.util.ArrayList;
025: import java.util.List;
026: import java.util.Set;
027: import java.util.TreeSet;
028:
029: import spoon.reflect.code.CtExpression;
030: import spoon.reflect.code.CtInvocation;
031: import spoon.reflect.code.CtLiteral;
032: import spoon.reflect.declaration.ModifierKind;
033: import spoon.reflect.reference.CtTypeReference;
034:
035: /**
036: * This class is a helper for runtime reflection.
037: */
038: public abstract class RtHelper {
039:
040: private RtHelper() {
041: }
042:
043: /**
044: * Gets all the runtime fields for a given class (including the
045: * superclasses').
046: */
047: public static Field[] getAllFields(Class<?> c) {
048: List<Field> fields = new ArrayList<Field>();
049: while (c != null && c != Object.class) {
050: for (Field f : c.getDeclaredFields()) {
051: fields.add(f);
052: }
053: // fields.addAll(Arrays.asList(c.getDeclaredFields()));
054: c = c.getSuperclass();
055: }
056: Field[] result = new Field[fields.size()];
057: return fields.toArray(result);
058: }
059:
060: /**
061: * Gets all the runtime methods for a given class or interface (including
062: * the superclasses' or interfaces').
063: */
064: public static Method[] getAllMethods(Class<?> c) {
065: List<Method> methods = new ArrayList<Method>();
066: if (c.isInterface()) {
067: getAllIMethods(c, methods);
068: } else {
069: while (c != null && c != Object.class) {
070: for (Method m : c.getDeclaredMethods())
071: methods.add(m);
072: // methods.addAll(Arrays.asList(c.getDeclaredMethods()));
073: c = c.getSuperclass();
074: }
075: }
076: Method[] result = new Method[methods.size()];
077: return methods.toArray(result);
078: }
079:
080: private static void getAllIMethods(Class<?> c, List<Method> methods) {
081: for (Method m : c.getDeclaredMethods())
082: methods.add(m);
083: for (Class<?> i : c.getInterfaces()) {
084: getAllIMethods(i, methods);
085: }
086: }
087:
088: /**
089: * Actually invokes from a compile-time invocation (by using runtime
090: * reflection).
091: */
092: @SuppressWarnings("unchecked")
093: public static <T> T invoke(CtInvocation<T> i)
094: throws NoSuchMethodException, IllegalAccessException,
095: InvocationTargetException {
096: Object target = i.getTarget() == null ? null
097: : ((CtLiteral<?>) i.getTarget()).getValue();
098: List<Object> args = new ArrayList<Object>();
099: for (CtExpression e : i.getArguments()) {
100: args.add(((CtLiteral<?>) e).getValue());
101: }
102: Class<?> c = i.getExecutable().getDeclaringType()
103: .getActualClass();
104: ArrayList<Class<?>> argTypes = new ArrayList<Class<?>>();
105: for (CtTypeReference<?> type : i.getExecutable()
106: .getParameterTypes()) {
107: argTypes.add(type.getActualClass());
108: }
109: return (T) c.getMethod(i.getExecutable().getSimpleName(),
110: argTypes.toArray(new Class[argTypes.size()])).invoke(
111: target, args.toArray());
112: }
113:
114: /**
115: * Return the set of modifiers defined by the modifiers integer
116: * (java.lang.reflect).
117: */
118: public static Set<ModifierKind> getModifiers(int mod) {
119: Set<ModifierKind> set = new TreeSet<ModifierKind>();
120: if (Modifier.isAbstract(mod)) {
121: set.add(ModifierKind.ABSTRACT);
122: }
123: if (Modifier.isFinal(mod)) {
124: set.add(ModifierKind.FINAL);
125: }
126: if (Modifier.isNative(mod)) {
127: set.add(ModifierKind.NATIVE);
128: }
129: if (Modifier.isPrivate(mod)) {
130: set.add(ModifierKind.PRIVATE);
131: }
132: if (Modifier.isProtected(mod)) {
133: set.add(ModifierKind.PROTECTED);
134: }
135: if (Modifier.isPublic(mod)) {
136: set.add(ModifierKind.PUBLIC);
137: }
138: if (Modifier.isStatic(mod)) {
139: set.add(ModifierKind.STATIC);
140: }
141: if (Modifier.isStrict(mod)) {
142: set.add(ModifierKind.STRICTFP);
143: }
144: if (Modifier.isSynchronized(mod)) {
145: set.add(ModifierKind.SYNCHRONIZED);
146: }
147: if (Modifier.isTransient(mod)) {
148: set.add(ModifierKind.TRANSIENT);
149: }
150: if (Modifier.isVolatile(mod)) {
151: set.add(ModifierKind.VOLATILE);
152: }
153: return set;
154: }
155:
156: }
|