All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jianggujin.modulelink.util.JResolverUtils Maven / Gradle / Ivy

/**
 * Copyright 2018 jianggujin (www.jianggujin.com).
 * 
 * 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.jianggujin.modulelink.util;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.jianggujin.modulelink.util.JLogFactory.JLog;
import com.jianggujin.modulelink.util.vfs.JVFS;

/**
 * 解析工具,用于定位查找类
 * 
 * @author jianggujin
 *
 */
public class JResolverUtils {
   private static final JLog logger = JLogFactory.getLog(JResolverUtils.class);

   private Set> matches = new HashSet>();
   /**
    * 需要排除的配置文件
    */
   private Set exclusions = new HashSet();

   private ClassLoader classloader;

   public Set getExclusions() {
      return exclusions;
   }

   public void setExclusions(Set exclusions) {
      JAssert.checkNotNull(exclusions, "exclusions must not be null");
      this.exclusions = exclusions;
   }

   public JResolverUtils withExclusions(Set exclusions) {
      this.setExclusions(exclusions);
      return this;
   }

   public JResolverUtils addExclusions(Collection exclusions) {
      if (exclusions != null) {
         this.exclusions.addAll(exclusions);
      }
      return this;
   }

   public JResolverUtils addExclusion(String exclusion) {
      JAssert.checkNotNull(exclusion, "exclusion must not be null");
      this.exclusions.add(exclusion);
      return this;
   }

   public JResolverUtils removeExclusion(String exclusion) {
      this.exclusions.remove(exclusion);
      return this;
   }

   public Set> getClasses() {
      return matches;
   }

   public ClassLoader getClassLoader() {
      return classloader == null ? Thread.currentThread().getContextClassLoader() : classloader;
   }

   public void setClassLoader(ClassLoader classloader) {
      this.classloader = classloader;
   }

   public JResolverUtils findImplementations(Class parent, String... packageNames) {
      if (packageNames == null) {
         return this;
      }

      JTest test = new JIsA(parent);
      for (String pkg : packageNames) {
         find(test, pkg);
      }

      return this;
   }

   public JResolverUtils findAnnotated(Class annotation, String... packageNames) {
      if (packageNames == null) {
         return this;
      }

      JTest test = new JAnnotatedWith(annotation);
      for (String pkg : packageNames) {
         find(test, pkg);
      }

      return this;
   }

   public JResolverUtils find(JTest test, String packageName) {
      String path = getPackagePath(packageName);

      try {
         List children = JVFS.getInstance().list(path);
         for (String child : children) {
            if (child.endsWith(".class")) {
               addIfMatching(test, child);
            }
         }
      } catch (IOException ioe) {
         logger.error("find error", ioe);
      }

      return this;
   }

   protected String getPackagePath(String packageName) {
      return packageName == null ? null : packageName.replace('.', '/');
   }

   protected void addIfMatching(JTest test, String fqn) {
      try {
         String externalName = fqn.substring(0, fqn.indexOf('.')).replace('/', '.');
         if (exclusions.contains(externalName)) {
            return;
         }
         ClassLoader loader = getClassLoader();
         Class type = loader.loadClass(externalName);
         if (test.matches(type)) {
            if (logger.isDebugEnabled()) {
               logger.debug("find match class:" + type);
            }
            matches.add((Class) type);
         }
      } catch (Throwable t) {
         logger.error("addIfMatching error", t);
      }
   }

   /**
    * 一个简单的测试接口用于判断类是否应该包含在返回结果中
    */
   public static interface JTest {
      boolean matches(Class type);
   }

   public static class JIsA implements JTest {
      private Class parent;

      public JIsA(Class parentType) {
         this.parent = parentType;
      }

      @Override
      public boolean matches(Class type) {
         return type != null && parent.isAssignableFrom(type);
      }

      @Override
      public String toString() {
         return "is assignable to " + parent.getSimpleName();
      }
   }

   public static class JAnnotatedWith implements JTest {
      private Class annotation;

      public JAnnotatedWith(Class annotation) {
         this.annotation = annotation;
      }

      @Override
      public boolean matches(Class type) {
         return type != null && type.isAnnotationPresent(annotation);
      }

      @Override
      public String toString() {
         return "annotated with @" + annotation.getSimpleName();
      }
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy