/* * Copyright 2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jdave.runner; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * Provides lists of class members (methods and inner classes) in the same * order as they have been declared in the source code. Requires that the * classes have been compiled with debug information (line numbers) included * in the bytecode and that the methods have a body (not native nor abstract). * * @author Esko Luontola * @since 4.1.2008 */ public final class ClassMemberSorter { private ClassMemberSorter() { } /** * @return the same as {@link Class#getClasses()} but in the same order as * declared in the source code. */ public static Class<?>[] getClasses(Class<?> declaringClass) { List<Class<?>> allDeclaredClasses = new ArrayList<Class<?>>(); for (Class<?> clazz : inheritanceHierarchyOf(declaringClass)) { Class<?>[] classes = contextClassesDeclaredIn(clazz); Arrays.sort(classes, new ClassLineNumberComparator()); allDeclaredClasses.addAll(Arrays.asList(classes)); } return allDeclaredClasses.toArray(new Class[allDeclaredClasses.size()]); } private static Class<?>[] contextClassesDeclaredIn(Class<?> clazz) { return clazz.getDeclaredClasses(); } private static List<Class<?>> inheritanceHierarchyOf(Class<?> declaringClass) { List<Class<?>> hierarchy = new ArrayList<Class<?>>(); Class<?> root = declaringClass; do { hierarchy.add(root); root = root.getSuperclass(); } while (root != null && !root.equals(Object.class)); Collections.reverse(hierarchy); return hierarchy; } /** * @return the same as {@link Class#getMethods()} but in the same order as * declared in the source code. */ public static Method[] getMethods(Class<?> clazz) { Method[] methods = clazz.getMethods(); Arrays.sort(methods, new MethodLineNumberComparator()); return methods; } }