content: /*
  *  Copyright Beijing 58 Information Technology Co.,Ltd.
  *
  *  Licensed to the Apache Software Foundation (ASF) under one
  *  or more contributor license agreements.  See the NOTICE file
  *  distributed with this work for additional information
  *  regarding copyright ownership.  The ASF licenses this file
  *  to you 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.bj58.argo.thirdparty;
  
  
  import com.google.common.base.Preconditions;
  
  import java.io.File;
  import java.io.FileFilter;
  import java.io.IOException;
  import java.net.JarURLConnection;
  import java.net.URL;
  import java.net.URLDecoder;
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.LinkedHashSet;
  import java.util.List;
  import java.util.Set;
  import java.util.jar.JarEntry;
  import java.util.jar.JarFile;
  
  
  
  /**
    *
    * ClassUtil
    *
    * 扫描指定包（包括jar）下的class文件 <br>
    *
    * @author Service Platform Architecture Team (spat@58.com)
    */
  public class ClassUtil {
  
      /**
       * Return all interfaces that the given class implements as array,
       * including ones implemented by superclasses.
       * <p>If the class itself is an interface, it gets returned as sole interface.
       * @param clazz the class to analyze for interfaces
       * @return all interfaces that the given object implements as array
       */
      public static Class<?>[] getAllInterfacesForClass(Class<?> clazz) {
          return getAllInterfacesForClass(clazz, null);
      }
      /**
       * Return all interfaces that the given class implements as array,
       * including ones implemented by superclasses.
       * <p>If the class itself is an interface, it gets returned as sole interface.
       * @param clazz the class to analyze for interfaces
       * @param classLoader the ClassLoader that the interfaces need to be visible in
       * (may be <code>null</code> when accepting all declared interfaces)
       * @return all interfaces that the given object implements as array
       */
      public static Class<?>[] getAllInterfacesForClass(Class<?> clazz, ClassLoader classLoader) {
          Set<Class> ifcs = getAllInterfacesForClassAsSet(clazz, classLoader);
          return ifcs.toArray(new Class[ifcs.size()]);
      }
      /**
       * Return all interfaces that the given class implements as Set,
       * including ones implemented by superclasses.
       * <p>If the class itself is an interface, it gets returned as sole interface.
       * @param clazz the class to analyze for interfaces
       * @param classLoader the ClassLoader that the interfaces need to be visible in
       * (may be <code>null</code> when accepting all declared interfaces)
       * @return all interfaces that the given object implements as Set
       */
      public static Set<Class> getAllInterfacesForClassAsSet(Class clazz, ClassLoader classLoader) {
          Preconditions.checkNotNull(clazz, "Class must not be null");
          if (clazz.isInterface() && isVisible(clazz, classLoader)) {
              return Collections.singleton(clazz);
          }
          Set<Class> interfaces = new LinkedHashSet<Class>();
          while (clazz != null) {
              Class<?>[] ifcs = clazz.getInterfaces();
              for (Class<?> ifc : ifcs) {
                  interfaces.addAll(getAllInterfacesForClassAsSet(ifc, classLoader));
              }
              clazz = clazz.getSuperclass();
          }
          return interfaces;
      }
  
  
      /**
       * Check whether the given class is visible in the given ClassLoader.
       * @param clazz the class to check (typically an interface)
       * @param classLoader the ClassLoader to check against (may be <code>null</code>,
       * in which case this method will always return <code>true</code>)
       */
      public static boolean isVisible(Class<?> clazz, ClassLoader classLoader) {
          if (classLoader == null) {
              return true;
          }
          try {
              Class<?> actualClass = classLoader.loadClass(clazz.getName());
              return (clazz == actualClass);
              // Else: different interface class found...
          }
          catch (ClassNotFoundException ex) {
              // No interface class found...
              return false;
          }
      }
  }
  