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

com.zusmart.basic.scanner.support.InternalScanner Maven / Gradle / Ivy

Go to download

基础模块,提供配置,日志,SPI,图排序,路径匹配,资源扫描,包扫描,常用工具类

There is a newer version: 0.0.3
Show newest version
package com.zusmart.basic.scanner.support;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import com.zusmart.basic.extension.ExtensionService;
import com.zusmart.basic.logging.Logger;
import com.zusmart.basic.logging.LoggerFactory;
import com.zusmart.basic.matcher.PathMatcher;
import com.zusmart.basic.scanner.ScannerClassResult;
import com.zusmart.basic.scanner.ScannerFilter;
import com.zusmart.basic.scanner.ScannerResourceResult;
import com.zusmart.basic.scanner.ScannerResult;
import com.zusmart.basic.scanner.ScannerResultType;
import com.zusmart.basic.toolkit.StringUtils;

@ExtensionService("internal")
public class InternalScanner extends AbstractScanner implements ScannerFilter {

	private static final Logger logger = LoggerFactory.getLogger(InternalScanner.class);

	public InternalScanner() {
		super(InternalScanner.class.getClassLoader());
		this.attachScannerFilter(this);
	}

	@Override
	protected Set doScan(Set scannerClassPackages, Set scannerResourcePackages) {
		Set result = new LinkedHashSet();
		this.doScanClassPackages(scannerClassPackages, result);
		this.doScanResourcePackages(scannerResourcePackages, result);
		return result;
	}

	@Override
	public boolean execute(String path, ScannerResultType type, Set scannerPatterns) {
		PathMatcher pathMatcher = this.getPathMatcher();
		for (String pattern : scannerPatterns) {
			if (type == ScannerResultType.Class) {
				if (pathMatcher.match(pattern, path)) {
					return true;
				}
			} else if (type == ScannerResultType.Resource) {
				if (pattern.equals(path) || pathMatcher.match(pattern, path)) {
					return true;
				}
			}
		}
		return false;
	}

	protected void doScanClassPackages(Set scannerClassPackages, Set sets) {
		if (null == scannerClassPackages || scannerClassPackages.size() == 0) {
			return;
		}
		this.doScannerPackages(scannerClassPackages, ScannerResultType.Class, sets);
	}

	protected void doScanResourcePackages(Set scannerResourcePackages, Set sets) {
		if (null == scannerResourcePackages || scannerResourcePackages.size() == 0) {
			return;
		}
		this.doScannerPackages(scannerResourcePackages, ScannerResultType.Resource, sets);
	}

	protected void doScannerPackages(Set scannerPackages, ScannerResultType resultType, Set sets) {
		ClassLoader classLoader = this.getClassLoader();
		for (String packageName : scannerPackages) {
			try {
				Enumeration urls = classLoader.getResources(packageName.replace(".", "/"));
				while (urls.hasMoreElements()) {
					URL url = urls.nextElement();
					String protocol = url.getProtocol();
					if (PROTOCOL_FILE.equals(protocol)) {
						if (resultType == ScannerResultType.Class) {
							this.findClassByDirs(packageName, url.getPath(), sets);
						} else if (resultType == ScannerResultType.Resource) {
							this.findResourceByDirs(packageName, url.getPath(), sets);
						}
					} else if (PROTOCOL_JARF.equals(protocol)) {
						JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
						if (resultType == ScannerResultType.Class) {
							this.findClassByJars(packageName, jarURLConnection.getJarFile(), sets);
						} else if (resultType == ScannerResultType.Resource) {
							this.findResourceByJars(packageName, jarURLConnection.getJarFile(), sets);
						}
					}
				}
			} catch (IOException e) {
				logger.warn(e.getMessage(), e);
			}
		}
	}

	protected void findResourceByDirs(String packageName, String parentPath, Set sets) {
		File parent = new File(parentPath);
		if (!parent.exists() || !parent.isDirectory()) {
			return;
		}
		File[] files = parent.listFiles(new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				return pathname.isDirectory() || (!pathname.getName().endsWith(CLASS_SUFFIX));
			}
		});
		if (null == files || files.length == 0) {
			return;
		}
		String currentPackageName = StringUtils.isBlank(packageName) ? "" : packageName + "/";
		for (int i = 0; i < files.length; i++) {
			File file = files[i];
			if (file.isDirectory()) {
				this.findResourceByDirs(String.format("%s%s", currentPackageName, file.getName()), file.getPath(), sets);
			} else {
				String currentResourceName = String.format("%s%s", currentPackageName, file.getName());
				if (!this.isFilterPass(currentResourceName, ScannerResultType.Resource)) {
					continue;
				}
				try {
					URL url = file.toURI().toURL();
					String name = file.getName();
					ScannerResourceResult scannerResourceResult = this.createScannerResourceResult(url, name);
					if (!this.isProcessorResourcePass(scannerResourceResult)) {
						continue;
					}
					sets.add(scannerResourceResult);
					logger.debug("found {}", scannerResourceResult);
				} catch (MalformedURLException e) {
					e.printStackTrace();
				}
			}
		}
	}

	protected void findClassByDirs(String packageName, String parentPath, Set sets) {
		File parent = new File(parentPath);
		if (!parent.exists() || !parent.isDirectory()) {
			return;
		}
		File[] files = parent.listFiles(new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				return pathname.isDirectory() || pathname.getName().endsWith(CLASS_SUFFIX);
			}
		});
		if (null == files || files.length == 0) {
			return;
		}
		String currentPackageName = StringUtils.isBlank(packageName) ? "" : packageName + ".";
		for (int i = 0; i < files.length; i++) {
			File file = files[i];
			if (file.isDirectory()) {
				this.findClassByDirs(String.format("%s%s", currentPackageName, file.getName()), file.getPath(), sets);
			} else {
				String currentClassName = file.getName();
				currentClassName = currentClassName.substring(0, currentClassName.length() - CLASS_SUFFIX.length());
				currentClassName = String.format("%s%s", currentPackageName, currentClassName);
				if (!this.isFilterPass(currentClassName, ScannerResultType.Class)) {
					continue;
				}
				Class currentClass = this.classForName(currentClassName);
				if (null == currentClass) {
					continue;
				}
				try {
					ScannerClassResult scannerClassResult = this.createScannerClassResult(file.toURI().toURL(), currentClass);
					if (!this.isProcessorClassPass(scannerClassResult)) {
						continue;
					}
					sets.add(scannerClassResult);
				} catch (MalformedURLException e) {
					logger.warn(e.getMessage(), e);
				}
			}
		}
	}

	protected void findResourceByJars(String packageName, JarFile jarFile, Set sets) {
		Enumeration entries = jarFile.entries();
		while (entries.hasMoreElements()) {
			JarEntry entry = entries.nextElement();
			String entryName = entry.getName();
			if (entry.isDirectory() || entryName.endsWith(CLASS_SUFFIX)) {
				continue;
			}
			if (!this.isFilterPass(entryName, ScannerResultType.Resource)) {
				continue;
			}
			try {
				String urlPath = String.format("jar:file:/%s!/%s", jarFile.getName().replace("\\", "/"), entryName);
				URL url = new URL(urlPath);
				String name = entryName.substring(entryName.lastIndexOf("/") + 1);
				ScannerResourceResult scannerResourceResult = this.createScannerResourceResult(url, name);
				if (!this.isProcessorResourcePass(scannerResourceResult)) {
					continue;
				}
				sets.add(scannerResourceResult);
			} catch (MalformedURLException e) {
				logger.warn(e.getMessage(), e);
			}
		}
	}

	protected void findClassByJars(String packageName, JarFile jarFile, Set sets) {
		Enumeration entries = jarFile.entries();
		while (entries.hasMoreElements()) {
			JarEntry entry = entries.nextElement();
			String entryName = entry.getName();
			if (!entryName.endsWith(CLASS_SUFFIX)) {
				continue;
			}
			String currentClassName = entryName.replace('/', '.');
			currentClassName = currentClassName.substring(0, currentClassName.length() - CLASS_SUFFIX.length());
			if (!this.isFilterPass(currentClassName, ScannerResultType.Class)) {
				continue;
			}
			Class currentClass = this.classForName(currentClassName);
			if (null == currentClass) {
				continue;
			}
			String urlPath = String.format("jar:file:/%s!/%s.class", jarFile.getName().replace("\\", "/"), currentClass.getName().replace(".", "/"));
			try {
				URL url = new URL(urlPath);
				ScannerClassResult scannerClassResult = this.createScannerClassResult(url, currentClass);
				if (!this.isProcessorClassPass(scannerClassResult)) {
					continue;
				}
				sets.add(scannerClassResult);
			} catch (MalformedURLException e) {
				logger.warn(e.getMessage(), e);
			}
		}
	}

	protected ScannerResourceResult createScannerResourceResult(URL url, String name) {
		return new InternalScannerResourceResult(url, name);
	}

	protected ScannerClassResult createScannerClassResult(URL url, Class currentClass) {
		return new InternalScannerClassResult(url, currentClass);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy