
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 extends String> 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 extends Annotation> 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 extends Annotation> annotation;
public JAnnotatedWith(Class extends Annotation> 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