/* * Copyright 2012 William Bernardet * * 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 com.googlecode.japi.checker; import java.util.ArrayList; import java.util.List; import com.googlecode.japi.checker.model.ClassData; import com.googlecode.japi.checker.model.MethodData; /** * Some common functions which ease the writing of rules. * */ public final class RuleHelpers { private RuleHelpers() {} /** * * For the following given inheritance tree: * <code> * A -> B -> C -> D * </code> * * A call to <code>isClassPartOfClassTree(loader, "B", "A");</code> will return true, as A inherits from B. * But calling <code>isClassPartOfClassTree(loader, "B", "C");</code> will return false. * </code> * * @param loader the loader to use for extracting class information. * @param classname the class to look for in the inheritance tree. * @param topLevelClassname the top-level element of the tree to start * @return Returns true if classname is found in topLevelClassname * inheritance tree (or equal to it), false otherwise. */ public static boolean isClassPartOfClassTree(ClassDataLoader loader, String classname, String topLevelClassname) { if (topLevelClassname != null) { if (classname.equals(topLevelClassname)) { return true; } ClassData superClass = loader.fromName(topLevelClassname); if (superClass != null) { return isClassPartOfClassTree(loader, classname, superClass.getSuperName()); } } return false; } /** * Return the list of all methods provided by this class including from * inheritance. * @param clazz the class to start recursing from. * @return All the methods implemented by the class or the interface. */ public static List<MethodData> getClassMethodRecursive(ClassData clazz) { List<MethodData> result = new ArrayList<MethodData>(); result.addAll(clazz.getMethods()); ClassData superClass = clazz.getClassDataLoader().fromName(clazz.getSuperName()); if (superClass != null) { for (MethodData method : getClassMethodRecursive(superClass)) { if (!containsSame(result, method)) { result.add(method); } } } // In case of interface let's include all interface inheritance tree. if (clazz.isInterface()) { for (String ifaceName : clazz.getInterfaces()) { ClassData iface = clazz.getClassDataLoader().fromName(ifaceName); if (iface != null) { for (MethodData method : getClassMethodRecursive(iface)) { if (!containsSame(result, method)) { result.add(method); } } } } } return result; } /** * Check if a list already contains a method similar to the one provided. * @param methods * @param method * @return */ private static boolean containsSame(List<MethodData> methods, MethodData method) { for (MethodData m : methods) { if (method.isSame(m)) { return true; } } return false; } }