From 515327023952336d85437d8b9a5e5f5334cad1ee Mon Sep 17 00:00:00 2001 From: Anton Romanov Date: Wed, 31 Mar 2021 11:18:49 +0400 Subject: [PATCH] #12 -- Need to detect project structure --- .../api/StructuralUnitIdentifier.java | 36 ++++++++++++++++-- .../extractor/heuristic/model/EntityUnit.java | 4 +- .../heuristic/model/MavenBuildTool.java | 18 +++++++++ .../heuristic/model/StructuralUnit.java | 15 +++++--- .../heuristic/service/JavaIdentifier.java | 37 ++++++++++++++++--- .../service/StructuralUnitService.java | 3 +- .../ru/ulstu/extractor/util/StringUtils.java | 28 ++++++++++++++ 7 files changed, 123 insertions(+), 18 deletions(-) create mode 100644 src/main/java/ru/ulstu/extractor/heuristic/model/MavenBuildTool.java create mode 100644 src/main/java/ru/ulstu/extractor/util/StringUtils.java diff --git a/src/main/java/ru/ulstu/extractor/heuristic/api/StructuralUnitIdentifier.java b/src/main/java/ru/ulstu/extractor/heuristic/api/StructuralUnitIdentifier.java index 2f95002..cbe6680 100644 --- a/src/main/java/ru/ulstu/extractor/heuristic/api/StructuralUnitIdentifier.java +++ b/src/main/java/ru/ulstu/extractor/heuristic/api/StructuralUnitIdentifier.java @@ -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 getEntityClasses(List projectFiles); + public List getEntityClasses(String projectPath, List projectFiles, List rootProjectFiles) { + String subDirectory = getSourceDirectory(projectFiles, rootProjectFiles); + return getEntityClasses(projectPath, subDirectory, projectFiles); + } + + protected abstract String getSourceDirectory(List projectFiles, List rootProjectFiles); + + public abstract List getEntityClasses(String projectPath, String subDirectory, List projectFiles); public abstract List getBusinessLogicClasses(); public abstract boolean isMultiModuleProject(); - public abstract BuildTool getBuildTool(); + public abstract Optional getBuildTool(List rootDirectoryFiles); protected abstract DetectorService getDetectorService(); @@ -33,9 +44,26 @@ public abstract class StructuralUnitIdentifier { protected abstract boolean isBusinessLogicClass(File file); protected Optional getMainProgrammingLanguage(List projectFiles) { - String detectedLanguage = getDetectorService().getDetectedLanguage("package ru.ulstu.extractor.heuristic.service;"); + Map 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> 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(); } diff --git a/src/main/java/ru/ulstu/extractor/heuristic/model/EntityUnit.java b/src/main/java/ru/ulstu/extractor/heuristic/model/EntityUnit.java index 5cfafad..3e99784 100644 --- a/src/main/java/ru/ulstu/extractor/heuristic/model/EntityUnit.java +++ b/src/main/java/ru/ulstu/extractor/heuristic/model/EntityUnit.java @@ -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); } } diff --git a/src/main/java/ru/ulstu/extractor/heuristic/model/MavenBuildTool.java b/src/main/java/ru/ulstu/extractor/heuristic/model/MavenBuildTool.java new file mode 100644 index 0000000..2910407 --- /dev/null +++ b/src/main/java/ru/ulstu/extractor/heuristic/model/MavenBuildTool.java @@ -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; + } +} diff --git a/src/main/java/ru/ulstu/extractor/heuristic/model/StructuralUnit.java b/src/main/java/ru/ulstu/extractor/heuristic/model/StructuralUnit.java index 4f6baa1..6c4ebd8 100644 --- a/src/main/java/ru/ulstu/extractor/heuristic/model/StructuralUnit.java +++ b/src/main/java/ru/ulstu/extractor/heuristic/model/StructuralUnit.java @@ -7,19 +7,22 @@ package ru.ulstu.extractor.heuristic.model; import java.io.File; +import static ru.ulstu.extractor.util.StringUtils.removePathPrefix; + public abstract class StructuralUnit { - private String pathToFile; - private String moduleName; + private final String pathToFile; + private final String unitName; - public StructuralUnit(File file) { - this.pathToFile = file.getPath(); + 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; } } diff --git a/src/main/java/ru/ulstu/extractor/heuristic/service/JavaIdentifier.java b/src/main/java/ru/ulstu/extractor/heuristic/service/JavaIdentifier.java index 1ed34e9..d27b65c 100644 --- a/src/main/java/ru/ulstu/extractor/heuristic/service/JavaIdentifier.java +++ b/src/main/java/ru/ulstu/extractor/heuristic/service/JavaIdentifier.java @@ -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 getEntityClasses(List projectFiles) { + public List getEntityClasses(String projectPath, String subDirectory, List 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 rootDirectoryFiles) { + //Todo: refactoring is highly recommended + Optional 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 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 projectFiles, List rootDirectoryFiles) { + Optional 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; diff --git a/src/main/java/ru/ulstu/extractor/heuristic/service/StructuralUnitService.java b/src/main/java/ru/ulstu/extractor/heuristic/service/StructuralUnitService.java index 1a18899..3772e5d 100644 --- a/src/main/java/ru/ulstu/extractor/heuristic/service/StructuralUnitService.java +++ b/src/main/java/ru/ulstu/extractor/heuristic/service/StructuralUnitService.java @@ -31,10 +31,11 @@ public class StructuralUnitService { public List getEntities(String repositoryUrl) throws IOException { File rootPath = gitRepositoryService.getProjectDirectoryFile(repositoryUrl); List projectFiles = directoryService.getFilesRecursively(rootPath); + List 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); } } diff --git a/src/main/java/ru/ulstu/extractor/util/StringUtils.java b/src/main/java/ru/ulstu/extractor/util/StringUtils.java new file mode 100644 index 0000000..ec448bc --- /dev/null +++ b/src/main/java/ru/ulstu/extractor/util/StringUtils.java @@ -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); + } +}