Scans a package in the classpath (of a particular classloader) for annotated components.

@param packageName the package name to scan
@param recursive whether or not to scan subpackages recursively
@param classLoader the classloader to use
@return
321125
public ClasspathScanDescriptorProvider scanPackage(final String packageName, final boolean recursive,
            final ClassLoader classLoader) {
        return scanPackage(packageName, recursive, classLoader, true);
    }
962446
public Set<Class<?>> getPackageAllClasses(String basePackage,
                                              boolean recursive) {
        Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
        String packageName = basePackage;
        if (packageName.endsWith(".")) {
            packageName = packageName
                    .substring(0, packageName.lastIndexOf('.'));
        }
        String package2Path = packageName.replace('.', '/');

        Enumeration<URL> dirs;
        try {
            dirs = Thread.currentThread().getContextClassLoader().getResources(
                    package2Path);
            while (dirs.hasMoreElements()) {
                URL url = dirs.nextElement();
                String protocol = url.getProtocol();
                if ("file".equals(protocol)) {
                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                    doScanPackageClassesByFile(classes, packageName, filePath, recursive);
                } else if ("jar".equals(protocol)) {
                    doScanPackageClassesByJar(packageName, url, recursive, classes);
                }
            }
        } catch (IOException e) {
            throw new LtsRuntimeException(e);
        }
        return classes;
    }
53839
synchronized public static <T> Set<ClassInfo> getNonAbstractSubClassInfoSet(Class<T> parentClass, String... packageNames) {
        if (packageNames == null || packageNames.length == 0) {
            packageNames = defaultPackages();
        }
        try (ScanResult scanResult =
                     new ClassGraph()
                             .enableAllInfo()
                             .whitelistPackages(packageNames)
                             .scan()) {
            ClassInfoList classInfos = parentClass.isInterface() ?
                    scanResult.getClassesImplementing(parentClass.getName()) :
                    scanResult.getSubclasses(parentClass.getName());
            return classInfos
                    .stream()
                    .filter(classInfo -> !classInfo.isAbstract())
                    .collect(Collectors.toSet());
        }
    }
474617
public static Predicate<Class<?>> inPackage(final String packageNamePrefix) {
        return clazz -> clazz.getPackage().getName().startsWith(packageNamePrefix);
    }
299376
public void scan(String classNamePattern, SaveHandler saveHandler) throws IOException {
        if (classNamePattern == null) {
            throw new IllegalArgumentException("classNamePattern must not be null");
        }

        classNamePattern = classNamePattern.replace(PACKAGE_SEPARATOR_CHAR, REGULAR_FILE_SEPARATOR_CHAR);
        String basePackageName = determineBasePackageName(classNamePattern);
        if (basePackageName == null) {
            return;
        }

        String subPattern;
        if (classNamePattern.length() > basePackageName.length()) {
            subPattern = classNamePattern.substring(basePackageName.length());
        } else {
            subPattern = StringUtils.EMPTY;
        }

        WildcardPattern pattern = WildcardPattern.compile(subPattern, REGULAR_FILE_SEPARATOR_CHAR);
        WildcardMatcher matcher = new WildcardMatcher(pattern);

        Enumeration<URL> resources = classLoader.getResources(basePackageName);

        if (!StringUtils.endsWith(basePackageName, REGULAR_FILE_SEPARATOR_CHAR)) {
            basePackageName += REGULAR_FILE_SEPARATOR_CHAR;
        }

        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();

            if (log.isDebugEnabled()) {
                log.debug("Scanning for components in path: " + resource.getFile());
            }

            if (isJarResource(resource)) {
                scanFromJarResource(resource, matcher, saveHandler);
            } else {
                scan(resource.getFile(), basePackageName, null, matcher, saveHandler);
            }
        }
    }
657823
private void definePackageIfNecessary(String className) {
		int lastDot = className.lastIndexOf('.');
		if (lastDot >= 0) {
			String packageName = className.substring(0, lastDot);
			if (getPackage(packageName) == null) {
				try {
					definePackage(className, packageName);
				}
				catch (IllegalArgumentException ex) {
					// Tolerate race condition due to being parallel capable
					if (getPackage(packageName) == null) {
						// This should never happen as the IllegalArgumentException
						// indicates that the package has already been defined and,
						// therefore, getPackage(name) should not have returned null.
						throw new AssertionError(
								"Package " + packageName + " has already been defined "
										+ "but it could not be found");
					}
				}
			}
		}
	}
440615
public static List<String> getAllClassesInPackage(String packageName) {
		List<String> classesNames = new Vector<>();
		// create scanner and disable default filters (that is the 'false' argument)
		final ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
		// add include filters which matches all the classes (or use your own)
		provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(".*")));

		// get matching classes defined in the package
		final Set<BeanDefinition> classes = provider.findCandidateComponents(packageName);

		// this is how you can load the class type from BeanDefinition instance
		for (BeanDefinition bean : classes) {
			classesNames.add(bean.getBeanClassName());
		}
		return classesNames;
	}
288549
protected boolean checkExcludePackages(String classPackageName) {
		if (excludePackages != null && excludePackages.length > 0) {
			WildcardHelper wildcardHelper = new WildcardHelper();

			// we really don't care about the results, just the boolean
			Map<String, String> matchMap = new HashMap<String, String>();

			for (String packageExclude : excludePackages) {
				int[] packagePattern = wildcardHelper.compilePattern(packageExclude);
				if (wildcardHelper.match(matchMap, classPackageName, packagePattern)) {
					return false;
				}
			}
		}
		return true;
	}
1076361
@Override
    public boolean analyzeJar(Analyzer analyzer) throws Exception {

        try {
        if (scanAgain) {

            //this will only have an effect on the first scan, because subsequent scanAgain
            //will use the errorMarker to decide if to scan again
            resetErrorMarker();

            List<String> newlyAddedPackages = new ArrayList<String>();

            System.out.println("ImportlessPackager plugin: iteration " + iteration);
            // set up exclude filter
            setupFilters(analyzer);
            // collect dependency packages
            Set<PackageRef> importedPackages = collectDependencies(analyzer);
            
            Jar outputJar = analyzer.getJar();
            //loop through the referred packages
            for (PackageRef ref : importedPackages) {

                String packageName = ref.getFQN();

                System.out.println("Seeking package " + packageName);

                boolean foundPackage = false;
                // locate the package in the classpath and add it the the export
                for (Jar src : analyzer.getClasspath()) {
               		if (src.getPackages().contains(packageName)) {
               			foundPackage = true;
                        System.out.println("Found matching pkg " + packageName + " from " +src.getSource().getAbsolutePath());
                         //only want to include the package itself, not any sub-packages
                         //can provide an Instruction to bnd for this, but it gets a bit weird:
                         //match the package name plus a / since everything in the package will
                         //have the package path followed by a separator.
                         //We use [/|/] to match the single / because bnd needs something to serve
                         //as a wildcard to enable regex matching (otherwise it just does an equals match)
                         //we can't use the other wildcards e.g. * ? because bnd processes them into
                         //.?, .* to do an any character match
                         //If we don't want any sub package content we can't allow any more slashes
                         //so use [^/]+ (i.e. not / 1 or more times)
                         outputJar.addAll(src, new Instruction(ref.getPath() + "[/|/][^/]+"));

                         newlyAddedPackages.add(packageName);

                         //we don't break the outer loop in case of split packages (ick!)
                         //since we might find some additional content for this package in another jar
                     }
                 }
                 if (!foundPackage) {
                	 //we couldn't find the package on the classpath, fail the build
                     //with a helpful message

                     String errorMsg = "Package " + packageName + " not found for inclusion in jar. Is the package available on the projects classpath?";
                     error(errorMsg);
                }
            }

            //add all the newly added packages to our global list so we don't check them again
            if (newlyAddedPackages.isEmpty()) {
                //no new packages, no further scanning required
                scanAgain = false;
            } else {
                addedPackages.addAll(newlyAddedPackages);
                iteration++;
                if (iteration > LAST_ITERATION) {
                    //there are new packages but we've run out of iterations, fail the build
                    error("Maximum number of plugin iterations reached, but there were still new packages to analyze. Consider adding more iterations.");
                }
            }

            //don't bother scanning again if we've already had an error
            if (scanAgain == true && errorMarker.exists())
                scanAgain = false;

        }
        } catch(Exception ex) {
            ex.printStackTrace();
            System.out.println(ex.getMessage());
        }

        //tell bnd to reanalyze the classpath if we are going to scan again
        return scanAgain;
    }
881659
public void scan(final String[] packages) {
        LOGGER.info("Scanning packages {}:", ArrayUtils.toString(packages));
        for (final String pkg : packages) {
            try {
                final String pkgFile = pkg.replace('.', '/');
                final Enumeration<URL> urls = getRootClassloader().getResources(pkgFile);
                while (urls.hasMoreElements()) {
                    final URL url = urls.nextElement();
                    try {
                        final URI uri = getURI(url);
                        LOGGER.debug("Scanning {}", uri);
                        scan(uri, pkgFile);
                    } catch (final URISyntaxException e) {
                        LOGGER.debug("URL {} cannot be converted to a URI", url, e);
                    }
                }
            } catch (final IOException ex) {
                throw new RuntimeException("The resources for the package" + pkg + ", could not be obtained",
                        ex);
            }
        }
        LOGGER.info(
                "Found {} matching classes and {} matching files",
                matchingClasses.size(),
                matchingFiles.size());
    }
844390
public Weld addPackages(boolean scanRecursively, Class<?>... packageClasses) {
        for (Class<?> packageClass : packageClasses) {
            addPackage(scanRecursively, packageClass);
        }
        return this;
    }
182107
public static Set<String> scanClassNames(final String packageName) throws IOException
	{
		return scanClassNames(packageName, false, true);
	}
305323
public static Class<?> findClassFromClassLoaders(final String className, final Iterable<ClassLoader> classLoaders)
        throws ClassNotFoundException, IllegalArgumentException {
        // Delegate
        return ClassLoaderSearchUtil.findClassFromClassLoaders(className, classLoaders);
    }
1147775
public Weld addPackage(boolean scanRecursively, Class<?> packageClass) {
        packages.add(new PackInfo(packageClass, scanRecursively));
        return this;
    }
1151416
@SuppressWarnings("unchecked")
    public static <T> Set<Class<T>> loadClasses(String packageName, Class<T> baseClassOrInterface)
    {
        Set<Class<T>> result = new HashSet<>();

        try
        {
            Set<String> classNames = getClassNamesFromPackage(packageName);
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            for (String className : classNames)
            {
                try
                {
                    Class< ? > clazz = classLoader.loadClass(packageName + "." + className);
                    if (!Modifier.isAbstract(clazz.getModifiers()) && baseClassOrInterface.isAssignableFrom(clazz))
                    {
                        result.add((Class<T>) clazz);
                    }
                }
                catch (Throwable e)
                {
                    logger.error(e, e);
                }

            }
            logger.info("Loaded " + result.size());
        }
        catch (Exception e)
        {
            logger.error(e, e);
        }

        return result;
    }
975875
public String java(GeneratedPackage generatedPackage, String javaClassName) {
        generatedPackageRestriction(generatedPackage);
        return java(generatedPackage.getPackageName(), javaClassName);
    }
1194339
public Set<Class<?>> findAndAddClassesInPackageByFile(JarFile jar, String packageDirName,
                                                          String packageName, boolean recursive) {
        LOGGER.debug("尝试扫描jar文件{}");
        Set<Class<?>> classes = new LinkedHashSet<>();
        LOGGER.debug("jar类型的扫描");
        // 获取jar
        // 从此jar包 得到一个枚举类
        Enumeration<JarEntry> entries = jar.entries();
        // 同样的进行循环迭代
        while (entries.hasMoreElements()) {
            // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
            JarEntry entry = entries.nextElement();
            String name = entry.getName();
            // 如果是以/开头的
            if (name.charAt(0) == '/') {
                // 获取后面的字符串
                name = name.substring(1);
            }
            // 如果前半部分和定义的包名相同
            if (name.startsWith(packageDirName)) {
                int idx = name.lastIndexOf('/');
                // 如果以"/"结尾 是一个包
                if (idx != -1) {
                    // 获取包名 把"/"替换成"."
                    packageName = name.substring(0, idx).replace('/', '.');
                }
                // 如果可以迭代下去 并且是一个包
                if ((idx != -1) || recursive) {
                    // 如果是一个.class文件 而且不是目录
                    if (name.endsWith(".class") && !entry.isDirectory()) {
                        // 去掉后面的".class" 获取真正的类名
                        String className = name.substring(packageName.length() + 1,
                            name.length() - 6);
                        className = packageName + "." + className;
                        try {
                            LOGGER.debug("尝试构建class：{}", className);
                            // 添加到classes
                            classes.add(classLoader.loadClass(className));
                        } catch (Throwable e) {
                            LOGGER.warn("找不到{}文件", className + ".class", e);
                        }
                    }
                }
            }
        }

        return classes;
    }