/** * Copyright 2015 itoshige1017@gmail.com * * This software is released under the MIT License. * http://opensource.org/licenses/mit-license.php */ package com.github.itoshige.testrail.util; import java.io.File; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.tools.DiagnosticCollector; import javax.tools.JavaCompiler; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.StandardLocation; import javax.tools.ToolProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.itoshige.testrail.annotation.Section; import com.github.itoshige.testrail.client.TestInitializerException; /** * target package class get * * @author itoshige * */ public class PackageClassSearchUtil { private static final Logger logger = LoggerFactory.getLogger(PackageClassSearchUtil.class); private static final String FILE_END = "Test.class"; /** sectionStore */ private final static ConcurrentHashMap<String, Set<String>> testClasses = CollectionUtil .newConcurrentMap(); public static Set<String> getTestClasses(String runId) { Set<String> testClassNames = testClasses.get(runId); if (testClassNames != null && !testClassNames.isEmpty()) return testClassNames; List<String> packages = ConfigrationUtil.getPackages(runId); for (String packageName : packages) { putTestClasses(runId, packageName); } if (testClasses.get(runId) == null || testClasses.get(runId).isEmpty()) throw new TestInitializerException(String.format("package name is invalid. runId:%s", runId)); return testClasses.get(runId); } private static void putTestClasses(String runId, String packageName) { logger.debug("target package:{}", packageName); Set<String> clazzes = getTestClassesByPackage(packageName); Set<String> putClasses = new HashSet<String>(); for (String clazz : clazzes) { if (TestRailUnitUtil.isTestRailDebugEnabled()) logger.debug("target class:{}", clazz); if (existTestClasses(clazz)) continue; putClasses.add(clazz); } testClasses.put(runId, putClasses); } private static boolean existTestClasses(String clazz) { if (testClasses == null || testClasses.keySet() == null) return false; if (TestRailUnitUtil.isTestRailDebugEnabled()) logger.debug("testClasses values:{} class:{} result:{}", new Object[] { testClasses.values(), clazz, testClasses.values().contains(clazz) }); return testClasses.values().contains(clazz); } private static Set<String> getTestClassesByPackage(String packageName) { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); JavaFileManager fm = compiler.getStandardFileManager(new DiagnosticCollector<JavaFileObject>(), null, null); Set<JavaFileObject.Kind> kind = new HashSet<JavaFileObject.Kind>() { private static final long serialVersionUID = 1L; { add(JavaFileObject.Kind.CLASS); } }; Set<String> sectionNamesInTestRun = new HashSet<String>(); try { for (JavaFileObject f : fm.list(StandardLocation.CLASS_PATH, packageName, kind, true)) { String fileName = f.getName(); if (!fileName.endsWith(FILE_END)) continue; String fileNameWithPackage = getFileNameWithPackage(fileName, packageName); Class<?> clazz = Class.forName(fileNameWithPackage); if (TestRailUnitUtil.isSkipClass(clazz)) continue; Section sectionName = clazz.getAnnotation(Section.class); if (TestRailUnitUtil.hasSection(sectionName)) { String trimSectionName = sectionName.name().trim(); sectionNamesInTestRun.add(trimSectionName); continue; } sectionNamesInTestRun.add(clazz.getSimpleName()); } return sectionNamesInTestRun; } catch (Exception e) { throw new TestInitializerException(String.format("couldn't get package classes. packageName:%s", packageName), e); } } private static String getFileNameWithPackage(String fileName, String packageName) { String filePackage = fileName.replace(File.separator, "."); Pattern pattern = Pattern.compile(new StringBuilder(packageName).append(".*").toString()); Matcher matcher = pattern.matcher(filePackage); if (matcher.find()) { String match = matcher.group(0); int last = match.lastIndexOf(".class"); return match.substring(0, last); } throw new TestInitializerException(String.format( "couldn't find package class. fileName:%s packageName:%s", fileName, packageName)); } }