#12 -- Need to detect project structure

This commit is contained in:
Anton Romanov 2021-03-31 11:18:49 +04:00
parent 2ee965a113
commit 5153270239
7 changed files with 124 additions and 19 deletions

View File

@ -12,17 +12,28 @@ import ru.ulstu.extractor.heuristic.service.DetectorService;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public abstract class StructuralUnitIdentifier {
public abstract List<StructuralUnit> getEntityClasses(List<File> projectFiles);
public List<StructuralUnit> getEntityClasses(String projectPath, List<File> projectFiles, List<File> rootProjectFiles) {
String subDirectory = getSourceDirectory(projectFiles, rootProjectFiles);
return getEntityClasses(projectPath, subDirectory, projectFiles);
}
protected abstract String getSourceDirectory(List<File> projectFiles, List<File> rootProjectFiles);
public abstract List<StructuralUnit> getEntityClasses(String projectPath, String subDirectory, List<File> projectFiles);
public abstract List<StructuralUnit> getBusinessLogicClasses();
public abstract boolean isMultiModuleProject();
public abstract BuildTool getBuildTool();
public abstract Optional<BuildTool> getBuildTool(List<File> rootDirectoryFiles);
protected abstract DetectorService getDetectorService();
@ -33,9 +44,26 @@ public abstract class StructuralUnitIdentifier {
protected abstract boolean isBusinessLogicClass(File file);
protected Optional<ProgrammingLanguage> getMainProgrammingLanguage(List<File> projectFiles) {
String detectedLanguage = getDetectorService().getDetectedLanguage("package ru.ulstu.extractor.heuristic.service;");
Map<String, Integer> projectFileLanguageFrequency = new HashMap<>();
projectFiles.forEach(projectFile -> {
try {
String detectedLanguage = getDetectorService().getDetectedLanguage(new String(Files.readAllBytes(projectFile.toPath())));
projectFileLanguageFrequency.put(detectedLanguage, projectFileLanguageFrequency.getOrDefault(detectedLanguage, 0) + 1);
} catch (IOException e) {
e.printStackTrace();
}
});
Optional<Map.Entry<String, Integer>> mostFrequentLanguageEntry = projectFileLanguageFrequency
.entrySet()
.stream()
.max(Map.Entry.comparingByValue());
if (mostFrequentLanguageEntry.isEmpty()) {
return Optional.empty();
}
ProgrammingLanguage programmingLanguage = getProgrammingLanguage();
return programmingLanguage.getName().equals(detectedLanguage)
return programmingLanguage.getName().equals(mostFrequentLanguageEntry.get().getKey())
? Optional.of(programmingLanguage)
: Optional.empty();
}

View File

@ -9,7 +9,7 @@ import java.io.File;
public class EntityUnit extends StructuralUnit {
public EntityUnit(File file) {
super(file);
public EntityUnit(String projectPath, File file) {
super(projectPath, file);
}
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
*/
package ru.ulstu.extractor.heuristic.model;
public class MavenBuildTool extends BuildTool {
public MavenBuildTool() {
super("Gradle");
}
@Override
protected boolean canAppliedToProject() {
return false;
}
}

View File

@ -7,19 +7,22 @@ package ru.ulstu.extractor.heuristic.model;
import java.io.File;
public abstract class StructuralUnit {
private String pathToFile;
private String moduleName;
import static ru.ulstu.extractor.util.StringUtils.removePathPrefix;
public StructuralUnit(File file) {
this.pathToFile = file.getPath();
public abstract class StructuralUnit {
private final String pathToFile;
private final String unitName;
public StructuralUnit(String projectPath, File file) {
this.pathToFile = removePathPrefix(file.getPath(), projectPath);
this.unitName = file.getName();
}
public String getPathToFile() {
return pathToFile;
}
public String getModuleName() {
return moduleName;
public String getUnitName() {
return unitName;
}
}

View File

@ -12,13 +12,17 @@ import org.springframework.stereotype.Service;
import ru.ulstu.extractor.heuristic.api.StructuralUnitIdentifier;
import ru.ulstu.extractor.heuristic.model.BuildTool;
import ru.ulstu.extractor.heuristic.model.EntityUnit;
import ru.ulstu.extractor.heuristic.model.GradleBuildTool;
import ru.ulstu.extractor.heuristic.model.JavaProgrammingLanguage;
import ru.ulstu.extractor.heuristic.model.MavenBuildTool;
import ru.ulstu.extractor.heuristic.model.ProgrammingLanguage;
import ru.ulstu.extractor.heuristic.model.StructuralUnit;
import ru.ulstu.extractor.util.StringUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
@ -36,10 +40,11 @@ public class JavaIdentifier extends StructuralUnitIdentifier {
}
@Override
public List<StructuralUnit> getEntityClasses(List<File> projectFiles) {
public List<StructuralUnit> getEntityClasses(String projectPath, String subDirectory, List<File> projectFiles) {
return projectFiles.stream()
.filter(file -> StringUtils.fileInSubdirectory(file.getPath(), projectPath, subDirectory))
.filter(this::isEntityClass)
.map(EntityUnit::new)
.map(file -> new EntityUnit(projectPath, file))
.collect(Collectors.toList());
}
@ -54,8 +59,18 @@ public class JavaIdentifier extends StructuralUnitIdentifier {
}
@Override
public BuildTool getBuildTool() {
return null;
public Optional getBuildTool(List<File> rootDirectoryFiles) {
//Todo: refactoring is highly recommended
Optional<GradleBuildTool> maybeGradleBuildTool = rootDirectoryFiles.stream()
.filter(file -> file.getName().equals("build.gradle"))
.findAny().map(file -> new GradleBuildTool());
if (maybeGradleBuildTool.isPresent()) {
return maybeGradleBuildTool;
}
return rootDirectoryFiles.stream()
.filter(file -> file.getName().equals("pom.xml"))
.findAny().map(file -> new MavenBuildTool());
}
@Override
@ -83,11 +98,23 @@ public class JavaIdentifier extends StructuralUnitIdentifier {
ParseResult<CompilationUnit> parseResult = parser.parse(file);
if (parseResult.getResult().isPresent() && parseResult.getResult().get().findCompilationUnit().isPresent()) {
return parseResult.getResult().get().getTypes().stream()
.anyMatch(clazz -> clazz.getAnnotations().stream().anyMatch(annotation -> annotation.getName().toString().equals(annotationDeclaration)));
.anyMatch(clazz -> clazz.getAnnotations().stream().anyMatch(annotation -> annotation.toString().startsWith(annotationDeclaration)));
}
return false;
}
@Override
protected String getSourceDirectory(List<File> projectFiles, List<File> rootDirectoryFiles) {
Optional<BuildTool> buildTool = getBuildTool(rootDirectoryFiles);
if (buildTool.isPresent()) {
if (buildTool.get() instanceof GradleBuildTool ||
buildTool.get() instanceof MavenBuildTool) {
return "src";
}
}
return "src";
}
@Override
protected boolean isBusinessLogicClass(File file) {
return false;

View File

@ -31,10 +31,11 @@ public class StructuralUnitService {
public List<StructuralUnit> getEntities(String repositoryUrl) throws IOException {
File rootPath = gitRepositoryService.getProjectDirectoryFile(repositoryUrl);
List<File> projectFiles = directoryService.getFilesRecursively(rootPath);
List<File> rootProjectFiles = directoryService.getDirectoryFiles(rootPath.toPath());
StructuralUnitIdentifier selectedIdentifier = structuralUnitIdentifiers.stream()
.filter(structuralUnitIdentifier -> structuralUnitIdentifier.canAppliedToProject(projectFiles))
.findAny()
.orElseThrow(() -> new RuntimeException("Identifier not found"));
return selectedIdentifier.getEntityClasses(projectFiles);
return selectedIdentifier.getEntityClasses(rootPath.getPath(), projectFiles, rootProjectFiles);
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
*/
package ru.ulstu.extractor.util;
import java.nio.file.FileSystems;
public class StringUtils {
public final static String EMPTY_STRING = "";
private final static String PATH_SEPARATOR = FileSystems.getDefault().getSeparator();
public static String addPathSeparator(String path) {
return path + PATH_SEPARATOR;
}
public static String removePathPrefix(String path, String prefix) {
if (prefix.endsWith(PATH_SEPARATOR)) {
return path.replace(prefix, EMPTY_STRING);
}
return path.replace(addPathSeparator(prefix), EMPTY_STRING);
}
public static boolean fileInSubdirectory(String filePath, String projectPath, String subDirectory) {
return filePath.startsWith(projectPath + PATH_SEPARATOR + subDirectory);
}
}