示例#1
0
  private void addClass(Class<?> c) {
    if (classes.add(c)) {
      if (c.getSuperclass() != null) {
        addClass(c.getSuperclass());
      }
      for (Class<?> sc : c.getInterfaces()) {
        addClass(sc);
      }
      for (Class<?> dc : c.getDeclaredClasses()) {
        addClass(dc);
      }
      for (Method m : c.getDeclaredMethods()) {
        addClass(m.getReturnType());
        for (Class<?> p : m.getParameterTypes()) {
          addClass(p);
        }
      }

      if (c != void.class && dimensions(c) < 2) {
        Class<?> arrayClass = Array.newInstance(c, 0).getClass();
        arrayClasses.put(c, arrayClass);
        addClass(arrayClass);
      }
    }
  }
  //
  // Find all the java.sql interfaces implemented by a class and find
  // the methods in those interfaces which raise
  // SQLFeatureNotSupportedException when called on the passed-in candidate object.
  //
  private void vetInterfaces(
      Object candidate,
      Class myClass,
      HashSet<String> unsupportedList,
      HashSet<String> notUnderstoodList)
      throws Exception {
    Class superClass = myClass.getSuperclass();

    if (superClass != null) {
      vetInterfaces(candidate, superClass, unsupportedList, notUnderstoodList);
    }

    //
    // The contract for Class.getInterfaces() states that the interfaces
    // come back in a deterministic order, namely, in the order that
    // they were declared in the "extends" clause.
    //
    Class<?>[] interfaces = myClass.getInterfaces();
    int interfaceCount = interfaces.length;

    for (int i = 0; i < interfaceCount; i++) {
      Class<?> iface = interfaces[i];

      if (iface.getPackage().getName().equals(SQL_PACKAGE_NAME)) {
        vetInterfaceMethods(candidate, iface, unsupportedList, notUnderstoodList);
      }

      vetInterfaces(candidate, iface, unsupportedList, notUnderstoodList);
    }
  }
    private static Optional<Method> lookup(
        Class<?> sourceClass, String methodName, Class<?>[] parameterTypes) {
      Method match;
      try {
        match = sourceClass.getMethod(methodName, parameterTypes);
      } catch (NoSuchMethodException e) {
        return Optional.absent();
      }

      LinkedList<Class<?>> queue = new LinkedList<Class<?>>();
      queue.add(sourceClass);
      while (!queue.isEmpty()) {
        Class<?> c = queue.removeFirst();
        try {
          match = c.getMethod(methodName, parameterTypes);
        } catch (NoSuchMethodException e) {
          // ignore
        }
        for (Class<?> interfaceType : c.getInterfaces()) {
          queue.addFirst(interfaceType);
        }
        if (c.getSuperclass() != null) {
          queue.addFirst(c.getSuperclass());
        }
      }
      match.setAccessible(true);
      return Optional.of(match);
    }
示例#4
0
  public Class[] getInterfacesFromClass(Class c) {

    Class[] cList;

    cList = c.getInterfaces();
    return cList;
  }
示例#5
0
  public void registerMockedClass(@Nonnull Class<?> mockedType) {
    if (!isMockedClass(mockedType)) {
      if (Proxy.isProxyClass(mockedType)) {
        mockedType = mockedType.getInterfaces()[0];
      }

      mockedClasses.add(mockedType);
    }
  }
  private static boolean testConvexPolygonArch() {
    boolean pass = true;
    int test = 1;
    int cnt;
    ConvexPolygon poly;
    Class cl;
    Class[] temp;

    System.out.println("ConvexPolygon architecture tests...");

    Point a = new Point(7, 7);
    Point b = new Point(0, 9);
    Point c = new Point(-3, -5);
    Point d = new Point(2, -6);
    Point e = new Point(12, 0);
    Point[] vertices = new Point[5];
    vertices[0] = new Point(a);
    vertices[1] = new Point(b);
    vertices[2] = new Point(c);
    vertices[3] = new Point(d);
    vertices[4] = new Point(e);

    poly = new ConvexPolygon(vertices, Color.cyan, false);

    cl = poly.getClass();

    pass &= test(cl.getConstructors().length == 1, test++);
    pass &= test((temp = cl.getInterfaces()).length == 1, test++);
    pass &= test(temp[0].getName().equals("Shape"), test++);
    pass &= test(verifyEqualsMethodSignature(cl), test++);

    cnt = countModifiers(cl.getDeclaredMethods(), Modifier.PUBLIC);
    pass &= test(cnt == 9, test++);

    cnt = cl.getFields().length;
    pass &= test(cnt == 0, test++);

    cnt = countModifiers(cl.getDeclaredFields(), Modifier.PROTECTED);
    pass &= test(cnt == 0, test++);

    cnt = countModifiers(cl.getDeclaredFields(), Modifier.PRIVATE);
    pass &= test(cnt == 3, test++);

    // Count and test number of of PACKAGE fields
    cnt =
        cl.getDeclaredFields().length
            - countModifiers(cl.getDeclaredFields(), Modifier.PRIVATE)
            - countModifiers(cl.getDeclaredFields(), Modifier.PROTECTED)
            - countModifiers(cl.getDeclaredFields(), Modifier.PUBLIC);
    pass &= test(cnt == 0, test++);

    return pass;
  }
示例#7
0
  private static void getAllInterfaces(Class<?> clazz, final HashSet<Class<?>> interfacesFound) {
    while (clazz != null) {
      final Class<?>[] interfaces = clazz.getInterfaces();
      for (Class<?> i : interfaces) {
        if (interfacesFound.add(i)) {
          getAllInterfaces(i, interfacesFound);
        }
      }

      clazz = clazz.getSuperclass();
    }
  }
 private static void collectFields(final Class clazz, final ArrayList<Field> result) {
   final Field[] fields = clazz.getDeclaredFields();
   result.addAll(Arrays.asList(fields));
   final Class superClass = clazz.getSuperclass();
   if (superClass != null) {
     collectFields(superClass, result);
   }
   final Class[] interfaces = clazz.getInterfaces();
   for (Class each : interfaces) {
     collectFields(each, result);
   }
 }
示例#9
0
 /**
  * Prints information about a class' parents and methods to a PrintWriter
  *
  * @param object
  * @param printer
  */
 public static void printClassInfo(Object object, PrintWriter printer) {
   if (object == null) {
     printer.println("null");
     return;
   }
   Class<?> type = object.getClass();
   printer.println(type);
   if (type.getSuperclass() != null) printer.println("extends " + type.getSuperclass());
   for (Class<?> interf : type.getInterfaces()) printer.println("implements " + interf);
   for (Method method : type.getMethods()) {
     printer.println(method);
   }
 }
示例#10
0
 private void makeInterfaceTypes(CompileUnit cu, ClassNode classNode, Class clazz) {
   Type[] interfaceTypes = clazz.getGenericInterfaces();
   if (interfaceTypes.length == 0) {
     classNode.setInterfaces(ClassNode.EMPTY_ARRAY);
   } else {
     Class[] interfaceClasses = clazz.getInterfaces();
     ClassNode[] ret = new ClassNode[interfaceTypes.length];
     for (int i = 0; i < interfaceTypes.length; i++) {
       ret[i] = makeClassNode(cu, interfaceTypes[i], interfaceClasses[i]);
     }
     classNode.setInterfaces(ret);
   }
 }
示例#11
0
 static Method[] getOverridableMethods(Class<?> clazz) {
   ArrayList<Method> list = new ArrayList<Method>();
   HashSet<String> skip = new HashSet<String>();
   // Check superclasses before interfaces so we always choose
   // implemented methods over abstract ones, even if a subclass
   // re-implements an interface already implemented in a superclass
   // (e.g. java.util.ArrayList)
   for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
     appendOverridableMethods(c, list, skip);
   }
   for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
     for (Class<?> intf : c.getInterfaces()) appendOverridableMethods(intf, list, skip);
   }
   return list.toArray(new Method[list.size()]);
 }
示例#12
0
  private void injectProperty(
      Object bean, Class<?> type, Object property, String alias, TypedValueGroup arguments)
      throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    NoSuchMethodException nsme = null;

    if (arguments != null && arguments.size() > 0) {
      Object[] props = new Object[arguments.size() + 1];
      props[0] = property;
      Class<?>[] types = new Class<?>[arguments.size() + 1];
      types[0] = type;

      arguments.reset();
      while (arguments.load(props, 1)) {
        try {
          addSetProperty(bean, types, alias, props);
          return;
        } catch (NoSuchMethodException x) {
          // not a problem
          nsme = x;
        }
      }
    } else {
      try {
        addSetProperty(bean, new Class<?>[] {type}, alias, property);
        return;
      } catch (NoSuchMethodException x) {
        // not a problem
        nsme = x;
      }
    }

    // now try the super classes
    Class<?>[] interfaces = type.getInterfaces();
    for (Class<?> face : interfaces) {
      try {
        injectProperty(bean, face, property, alias, arguments);
        return;
      } catch (NoSuchMethodException x) {
        continue;
      }
    }
    Class<?> supertype = type.getSuperclass();
    if (supertype != null) {
      injectProperty(bean, supertype, property, alias, arguments);
    } else {
      throw nsme;
    }
  }
示例#13
0
 private static void _addSuperTypes(
     Class<?> cls, Class<?> endBefore, Collection<Class<?>> result, boolean addClassItself) {
   if (cls == endBefore || cls == null || cls == Object.class) {
     return;
   }
   if (addClassItself) {
     if (result.contains(cls)) { // already added, no need to check supers
       return;
     }
     result.add(cls);
   }
   for (Class<?> intCls : cls.getInterfaces()) {
     _addSuperTypes(intCls, endBefore, result, true);
   }
   _addSuperTypes(cls.getSuperclass(), endBefore, result, true);
 }
  private static boolean testTriangleArch() {
    boolean pass = true;
    int test = 1;
    int cnt;
    Triangle tri;
    Class cl;
    Class[] temp;

    System.out.println("Triangle architecture tests...");

    Point a = new Point(0, 0);
    Point b = new Point(3, 0);
    Point c = new Point(0, 4);
    tri = new Triangle(a, b, c, Color.cyan, false);

    cl = tri.getClass();

    pass &= test(cl.getConstructors().length == 1, test++);
    pass &= test((temp = cl.getInterfaces()).length == 1, test++);
    pass &= test(temp[0].getName().equals("Shape"), test++);
    pass &= test(verifyEqualsMethodSignature(cl), test++);

    cnt = countModifiers(cl.getDeclaredMethods(), Modifier.PUBLIC);
    pass &= test(cnt == 13, test++);

    cnt = cl.getFields().length;
    pass &= test(cnt == 0, test++);

    cnt = countModifiers(cl.getDeclaredFields(), Modifier.PROTECTED);
    pass &= test(cnt == 0, test++);

    cnt = countModifiers(cl.getDeclaredFields(), Modifier.PRIVATE);
    pass &= test(cnt == 5, test++);

    // Count and test number of of PACKAGE fields
    cnt =
        cl.getDeclaredFields().length
            - countModifiers(cl.getDeclaredFields(), Modifier.PRIVATE)
            - countModifiers(cl.getDeclaredFields(), Modifier.PROTECTED)
            - countModifiers(cl.getDeclaredFields(), Modifier.PUBLIC);
    pass &= test(cnt == 0, test++);

    return pass;
  }
示例#15
0
  static PropertyDescriptor[] getInterfacePropertyDescriptors(Class<?> interfaceClass) {
    List<PropertyDescriptor> propDescriptors = new ArrayList<PropertyDescriptor>();
    // Add prop descriptors for interface passed in
    propDescriptors.addAll(Arrays.asList(BeanUtils.getPropertyDescriptors(interfaceClass)));

    // Look for interface inheritance. If super interfaces are found, recurse up the hierarchy tree
    // and add prop
    // descriptors for each interface found.
    // PropertyUtils.getPropertyDescriptors() does not correctly walk the inheritance hierarchy for
    // interfaces.
    Class<?>[] interfaces = interfaceClass.getInterfaces();
    if (interfaces != null) {
      for (Class<?> superInterfaceClass : interfaces) {
        List<PropertyDescriptor> superInterfacePropertyDescriptors =
            Arrays.asList(getInterfacePropertyDescriptors(superInterfaceClass));
        /*
         * #1814758
         * Check for existing descriptor with the same name to prevent 2 property descriptors with the same name being added
         * to the result list.  This caused issues when getter and setter of an attribute on different interfaces in
         * an inheritance hierarchy
         */
        for (PropertyDescriptor superPropDescriptor : superInterfacePropertyDescriptors) {
          PropertyDescriptor existingPropDescriptor =
              findPropDescriptorByName(propDescriptors, superPropDescriptor.getName());
          if (existingPropDescriptor == null) {
            propDescriptors.add(superPropDescriptor);
          } else {
            try {
              if (existingPropDescriptor.getReadMethod() == null) {
                existingPropDescriptor.setReadMethod(superPropDescriptor.getReadMethod());
              }
              if (existingPropDescriptor.getWriteMethod() == null) {
                existingPropDescriptor.setWriteMethod(superPropDescriptor.getWriteMethod());
              }
            } catch (IntrospectionException e) {
              throw new MappingException(e);
            }
          }
        }
      }
    }
    return propDescriptors.toArray(new PropertyDescriptor[propDescriptors.size()]);
  }
 @Override
 public List<ReferenceTypeUsage> getAllAncestors(Resolver resolver) {
   List<ReferenceTypeUsage> ancestors = new ArrayList<>();
   if (clazz.getSuperclass() != null) {
     ReferenceTypeUsage superTypeDefinition =
         toReferenceTypeUsage(clazz.getSuperclass(), clazz.getGenericSuperclass());
     ancestors.add(superTypeDefinition);
     ancestors.addAll(superTypeDefinition.getAllAncestors(resolver));
   }
   int i = 0;
   for (Class<?> interfaze : clazz.getInterfaces()) {
     Type genericInterfaze = clazz.getGenericInterfaces()[i];
     ReferenceTypeUsage superTypeDefinition = toReferenceTypeUsage(interfaze, genericInterfaze);
     ancestors.add(superTypeDefinition);
     ancestors.addAll(superTypeDefinition.getAllAncestors(resolver));
     i++;
   }
   return ancestors;
 }
  private static boolean testCircleArch() {
    boolean pass = true;
    int test = 1;
    int cnt;
    Circle circle;
    Class cl;
    Class[] temp;

    System.out.println("Circle architecture tests...");

    circle = new Circle(5.6789, new Point(-99, 66), Color.cyan, false);

    cl = circle.getClass();

    pass &= test(cl.getConstructors().length == 1, test++);
    pass &= test((temp = cl.getInterfaces()).length == 1, test++);
    pass &= test(temp[0].getName().equals("Shape"), test++);
    pass &= test(verifyEqualsMethodSignature(cl), test++);

    cnt = countModifiers(cl.getDeclaredMethods(), Modifier.PUBLIC);
    pass &= test(cnt == 10, test++);

    cnt = cl.getFields().length;
    pass &= test(cnt == 0, test++);

    cnt = countModifiers(cl.getDeclaredFields(), Modifier.PROTECTED);
    pass &= test(cnt == 0, test++);

    cnt = countModifiers(cl.getDeclaredFields(), Modifier.PRIVATE);
    pass &= test(cnt == 4, test++);

    // Count and test number of of PACKAGE fields
    cnt =
        cl.getDeclaredFields().length
            - countModifiers(cl.getDeclaredFields(), Modifier.PRIVATE)
            - countModifiers(cl.getDeclaredFields(), Modifier.PROTECTED)
            - countModifiers(cl.getDeclaredFields(), Modifier.PUBLIC);
    pass &= test(cnt == 0, test++);

    return pass;
  }
示例#18
0
  // Needed by NativeJavaObject serializer
  public static void writeAdapterObject(Object javaObject, ObjectOutputStream out)
      throws IOException {
    Class<?> cl = javaObject.getClass();
    out.writeObject(cl.getSuperclass().getName());

    Class<?>[] interfaces = cl.getInterfaces();
    String[] interfaceNames = new String[interfaces.length];

    for (int i = 0; i < interfaces.length; i++) interfaceNames[i] = interfaces[i].getName();

    out.writeObject(interfaceNames);

    try {
      Object delegee = cl.getField("delegee").get(javaObject);
      out.writeObject(delegee);
      return;
    } catch (IllegalAccessException e) {
    } catch (NoSuchFieldException e) {
    }
    throw new IOException();
  }
示例#19
0
  /**
   * Return the type distance between the child and parent types. The child type must be a subtype
   * of the parent. The type distance between a class and itself is 0; the distance from a class to
   * one of its immediate supertypes (superclass or a directly implemented interface) is 1; deeper
   * distances are computed recursively.
   *
   * @param child The child type
   * @param parent The parent type
   * @return The type distance
   * @throws IllegalArgumentException if {@code child} is not a subtype of {@code parent}.
   */
  public static int getTypeDistance(@Nonnull Class<?> child, @Nonnull Class<?> parent) {
    Preconditions.notNull("child class", child);
    Preconditions.notNull("parent class", parent);

    if (child.equals(parent)) {
      // fast-path same-class tests
      return 0;
    } else if (!parent.isAssignableFrom(child)) {
      // if child does not extend from the parent, return -1
      throw new IllegalArgumentException("child not a subclass of parent");
    } else if (!parent.isInterface()) {
      // if the parent is not an interface, we only need to follower superclasses
      int distance = 0;
      Class<?> cur = child;
      while (!cur.equals(parent)) {
        distance++;
        cur = cur.getSuperclass();
      }
      return distance;
    } else {
      // worst case, recursively compute the type
      // recursion is safe, as types aren't too deep except in crazy-land
      int minDepth = Integer.MAX_VALUE;
      Class<?> sup = child.getSuperclass();
      if (sup != null && parent.isAssignableFrom(sup)) {
        minDepth = getTypeDistance(sup, parent);
      }
      for (Class<?> iface : child.getInterfaces()) {
        if (parent.isAssignableFrom(iface)) {
          int d = getTypeDistance(iface, parent);
          if (d < minDepth) {
            minDepth = d;
          }
        }
      }
      // minDepth now holds the depth of the superclass with shallowest depth
      return minDepth + 1;
    }
  }
示例#20
0
  public Type navigateParameterized(String name, Type[] params) throws OclTypeException {
    Type ret = Basic.navigateAnyParameterized(name, params);
    if (ret != null) return ret;

    Method foundmethod = null;

    // this is very similar to tudresden.ocl.lib.OclAnyImpl.findMethod
    // if you find a bug here, its probably there as well.

    // suprisingly one has not to go after interfaces since methods
    // inherited from interfaces are automatically included into the
    // implementing class. This does not happen for methods inherited
    // from the superclass, so we have to ascend to all superclasses.

    // unfortunately the above is only true for classes, getSuperclass invoked
    // on an interface returns null, regardless of the interfaces extended by the
    // interface. Therefore, we need to check out getInterfaces() if iclass is
    // an interface
    HashSet hsVisited = new HashSet();
    LinkedList llToVisit = new LinkedList();
    if (c.isInterface()) {
      // as we're dealing with actual instances, it can be assumed that Object is
      // a superclass
      llToVisit.add(java.lang.Object.class);
    }

    classloop:
    for (Class iclass = c; iclass != null; ) // iclass=iclass.getSuperclass())
    {
      Method[] methods = iclass.getDeclaredMethods();
      methodloop:
      for (int i = 0; i < methods.length; i++) {
        if (!name.equals(methods[i].getName())) continue methodloop;
        Class[] methodparams = methods[i].getParameterTypes();
        if (params.length != methodparams.length) continue methodloop;

        System.err.print("Checking method " + name + " (");
        for (int j = 0; j < methodparams.length; j++) {
          if (j != 0) {
            System.err.print(", ");
          }

          System.err.print(methodparams[j]);
        }
        System.err.println(")");

        for (int j = 0; j < params.length; j++)
          if (!params[j].conformsTo(getTypeForClass(methodparams[j]))) {
            System.err.println("No conformance for paramter # " + j);
            continue methodloop;
          }
        if (foundmethod == null) foundmethod = methods[i];
        else throw new OclTypeException("ambigious method " + name + " of " + c + ") queried.");
        break classloop;
      }

      // determine classes to be visited
      if (iclass.isInterface()) {
        Class[] ca = iclass.getInterfaces();
        for (int i = 0; i < ca.length; i++) {
          if (!hsVisited.contains(ca[i])) {
            llToVisit.add(ca[i]);
          }
        }
      } else {
        if (!hsVisited.contains(iclass.getSuperclass())) {
          llToVisit.add(iclass.getSuperclass());
        }
      }

      // mark current class visited
      hsVisited.add(iclass);

      // go to next class
      if (!llToVisit.isEmpty()) {
        iclass = (Class) llToVisit.remove(0);
      } else {
        iclass = null;
      }
    }

    if (foundmethod == null) {
      StringBuffer sb = new StringBuffer();
      sb.append(c.toString() + " has no method " + name + " with parameters (");
      for (int i = 0; i < params.length; i++) {
        if (i != 0) sb.append(", ");
        sb.append(params[i] + "/" + params[i]);
      }
      sb.append(")");
      throw new OclTypeException(sb.toString());
    }

    return getTypeForClass(foundmethod.getReturnType());
  }
  /** Calculates a MD5 digest of the class. */
  public String getDigest() {
    try {
      if (_className == null || "".equals(_className)) return "";

      DynamicClassLoader loader =
          (DynamicClassLoader) Thread.currentThread().getContextClassLoader();

      ClassLoader tmpLoader = loader.getNewTempClassLoader();

      Class cl = Class.forName(_className, false, tmpLoader);

      if (cl == null) return "";

      MessageDigest digest = MessageDigest.getInstance("MD5");

      addDigest(digest, cl.getName());

      addDigest(digest, cl.getModifiers());

      Class superClass = cl.getSuperclass();
      if (superClass != null) addDigest(digest, superClass.getName());

      Class[] interfaces = cl.getInterfaces();
      for (int i = 0; i < interfaces.length; i++) addDigest(digest, interfaces[i].getName());

      Field[] fields = cl.getDeclaredFields();

      Arrays.sort(fields, new FieldComparator());

      if (_checkFields) {
        for (Field field : fields) {
          if (Modifier.isPrivate(field.getModifiers()) && !_checkPrivate) continue;
          if (Modifier.isProtected(field.getModifiers()) && !_checkProtected) continue;

          addDigest(digest, field.getName());
          addDigest(digest, field.getModifiers());
          addDigest(digest, field.getType().getName());

          addDigest(digest, field.getAnnotations());
        }
      }

      Method[] methods = cl.getDeclaredMethods();
      Arrays.sort(methods, new MethodComparator());

      for (int i = 0; i < methods.length; i++) {
        Method method = methods[i];

        if (Modifier.isPrivate(method.getModifiers()) && !_checkPrivate) continue;
        if (Modifier.isProtected(method.getModifiers()) && !_checkProtected) continue;
        if (Modifier.isStatic(method.getModifiers()) && !_checkStatic) continue;

        addDigest(digest, method.getName());
        addDigest(digest, method.getModifiers());
        addDigest(digest, method.getName());

        Class[] param = method.getParameterTypes();
        for (int j = 0; j < param.length; j++) addDigest(digest, param[j].getName());

        addDigest(digest, method.getReturnType().getName());

        Class[] exn = method.getExceptionTypes();
        for (int j = 0; j < exn.length; j++) addDigest(digest, exn[j].getName());

        addDigest(digest, method.getAnnotations());
      }

      byte[] digestBytes = new byte[256];

      int len = digest.digest(digestBytes, 0, digestBytes.length);

      return digestToBase64(digestBytes, len);
    } catch (Exception e) {
      log.log(Level.FINER, e.toString(), e);

      return "";
    }
  }
示例#22
0
  private static void discoverAccessibleMethods(
      Class<?> clazz,
      Map<MethodSignature, Method> map,
      boolean includeProtected,
      boolean includePrivate) {
    if (Modifier.isPublic(clazz.getModifiers()) || includePrivate) {
      try {
        if (includeProtected || includePrivate) {
          while (clazz != null) {
            try {
              Method[] methods = clazz.getDeclaredMethods();
              for (int i = 0; i < methods.length; i++) {
                Method method = methods[i];
                int mods = method.getModifiers();

                if (Modifier.isPublic(mods) || Modifier.isProtected(mods) || includePrivate) {
                  if (includePrivate) method.setAccessible(true);
                  map.put(new MethodSignature(method), method);
                }
              }
              clazz = clazz.getSuperclass();
            } catch (SecurityException e) {
              // Some security settings (i.e., applets) disallow
              // access to Class.getDeclaredMethods. Fall back to
              // Class.getMethods.
              Method[] methods = clazz.getMethods();
              for (int i = 0; i < methods.length; i++) {
                Method method = methods[i];
                MethodSignature sig = new MethodSignature(method);
                if (map.get(sig) == null) map.put(sig, method);
              }
              break; // getMethods gets superclass methods, no
              // need to loop any more
            }
          }
        } else {
          Method[] methods = clazz.getMethods();
          for (int i = 0; i < methods.length; i++) {
            Method method = methods[i];
            MethodSignature sig = new MethodSignature(method);
            map.put(sig, method);
          }
        }
        return;
      } catch (SecurityException e) {
        Context.reportWarning(
            "Could not discover accessible methods of class "
                + clazz.getName()
                + " due to lack of privileges, "
                + "attemping superclasses/interfaces.");
        // Fall through and attempt to discover superclass/interface
        // methods
      }
    }

    Class<?>[] interfaces = clazz.getInterfaces();
    for (int i = 0; i < interfaces.length; i++) {
      discoverAccessibleMethods(interfaces[i], map, includeProtected, includePrivate);
    }
    Class<?> superclass = clazz.getSuperclass();
    if (superclass != null) {
      discoverAccessibleMethods(superclass, map, includeProtected, includePrivate);
    }
  }