package de.refactoringbot.services.main; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.TrueFileFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.PackageDeclaration; import com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter; import java.nio.file.Files; import java.nio.file.Paths; /** * This class has methods that work with Files and Folders of Java-Projects. * * @author Stefan Basaric * */ @Service public class FileService { private static final Logger logger = LoggerFactory.getLogger(FileService.class); /** * This method returns all Javafile-Paths of a project from a configuration. * * @param repoFolderPath * @return allJavaFiles * @throws IOException */ public List<String> getAllJavaFiles(String repoFolderPath) throws IOException { // Init all java files path-list List<String> allJavaFiles = new ArrayList<>(); // Get root folder of project File dir = new File(repoFolderPath); // Get paths to all java files of the project List<File> files = (List<File>) FileUtils.listFiles(dir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE); for (File file : files) { if (file.getCanonicalPath().endsWith(".java")) { allJavaFiles.add(file.getCanonicalPath()); } } return allJavaFiles; } /** * This method returns all root folders' absolute paths of the given java files * (like the src folder or the src/main/java folder of maven projects) * * @param allJavaFiles * @return javaRoots * @throws FileNotFoundException */ public List<String> findJavaRoots(List<String> allJavaFiles) throws FileNotFoundException { Set<String> javaRoots = new HashSet<>(); for (String javaFile : allJavaFiles) { FileInputStream filepath = new FileInputStream(javaFile); CompilationUnit compilationUnit; try { compilationUnit = LexicalPreservingPrinter.setup(StaticJavaParser.parse(filepath)); } catch (Exception e) { logger.error(e.getMessage(), e); continue; } File file = new File(javaFile); List<PackageDeclaration> packageDeclarations = compilationUnit.findAll(PackageDeclaration.class); if (!packageDeclarations.isEmpty()) { // current java file should contain exactly one package declaration PackageDeclaration packageDeclaration = packageDeclarations.get(0); String rootPackage = packageDeclaration.getNameAsString().split("\\.")[0]; String javaRoot = file.getAbsolutePath() .split(Pattern.quote(File.separator) + rootPackage + Pattern.quote(File.separator))[0]; // If we have a made-up package name the path will not exist, so we don't add it if (Files.exists(Paths.get(javaRoot))) { javaRoots.add(javaRoot); } } } return new ArrayList<>(javaRoots); } }