#12 -- Get file content for specific commit
This commit is contained in:
parent
bf611faa38
commit
4265441490
@ -29,18 +29,24 @@ public abstract class StructuralUnitIdentifier {
|
||||
return getEntityClasses(projectPath, subDirectory, projectFiles);
|
||||
}
|
||||
|
||||
public abstract boolean canAppliedToCode(String sourceCode);
|
||||
|
||||
public abstract boolean canAppliedToFile(File projectFile);
|
||||
|
||||
public abstract boolean canAppliedToProject(String projectPath, List<File> projectFiles, List<File> rootProjectFiles);
|
||||
|
||||
public abstract boolean isEntityClass(File file);
|
||||
|
||||
public abstract boolean isEntityClass(String sourceCode);
|
||||
|
||||
protected abstract boolean isBusinessLogicClass(File file);
|
||||
|
||||
public abstract List<StructuralUnit> getBusinessLogicClasses();
|
||||
|
||||
public abstract boolean isMultiModuleProject();
|
||||
|
||||
public abstract Optional<BuildTool> getBuildTool(List<File> rootDirectoryFiles);
|
||||
|
||||
public abstract boolean canAppliedToProject(String projectPath, List<File> projectFiles, List<File> rootProjectFiles);
|
||||
|
||||
public abstract boolean canAppliedToFile(File projectFile);
|
||||
|
||||
protected abstract List<StructuralUnit> getEntityClasses(String projectPath, String subDirectory, List<File> projectFiles);
|
||||
|
||||
protected abstract String getSourceDirectory(List<File> rootProjectFiles);
|
||||
@ -51,8 +57,6 @@ public abstract class StructuralUnitIdentifier {
|
||||
|
||||
protected abstract ProgrammingLanguage getProgrammingLanguage();
|
||||
|
||||
protected abstract boolean isBusinessLogicClass(File file);
|
||||
|
||||
protected Optional<ProgrammingLanguage> getMainProgrammingLanguage(String projectPath, List<File> projectFiles, List<File> rootProjectFiles) {
|
||||
String subDirectory = getSourceDirectory(rootProjectFiles);
|
||||
Map<ProgrammingLanguage, Integer> projectFileLanguageFrequency = new HashMap<>();
|
||||
|
@ -10,7 +10,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ru.ulstu.extractor.heuristic.model.StructuralUnit;
|
||||
import ru.ulstu.extractor.heuristic.service.StructuralUnitService;
|
||||
import ru.ulstu.extractor.service.GitRepositoryService;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@ -18,13 +20,17 @@ import java.util.List;
|
||||
@RequestMapping("StructuralUnitController")
|
||||
public class StructuralUnitController {
|
||||
private final StructuralUnitService structuralUnitService;
|
||||
private final GitRepositoryService gitRepositoryService;
|
||||
|
||||
public StructuralUnitController(StructuralUnitService structuralUnitService) {
|
||||
public StructuralUnitController(StructuralUnitService structuralUnitService,
|
||||
GitRepositoryService gitRepositoryService) {
|
||||
this.structuralUnitService = structuralUnitService;
|
||||
this.gitRepositoryService = gitRepositoryService;
|
||||
}
|
||||
|
||||
@GetMapping("get-entities")
|
||||
public List<StructuralUnit> getEntities(String repositoryUrl) throws IOException {
|
||||
return structuralUnitService.getEntities(repositoryUrl);
|
||||
File rootPath = gitRepositoryService.getProjectDirectoryFile(repositoryUrl);
|
||||
return structuralUnitService.getEntities(rootPath);
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ import ru.ulstu.extractor.heuristic.model.StructuralUnit;
|
||||
import ru.ulstu.extractor.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
@ -27,6 +28,7 @@ import static ru.ulstu.extractor.heuristic.service.DetectorService.LangDetectScr
|
||||
|
||||
@Service
|
||||
public class JavaIdentifier extends StructuralUnitIdentifier {
|
||||
private static final String ENTITY_ANNOTATION = "@Entity";
|
||||
private final DetectorService detectorService;
|
||||
private final BuildToolService buildToolService;
|
||||
private final ProgrammingLanguageService programmingLanguageService;
|
||||
@ -49,6 +51,10 @@ public class JavaIdentifier extends StructuralUnitIdentifier {
|
||||
return getMainProgrammingLanguage(projectFile, LOW).orElse(null) instanceof JavaProgrammingLanguage;
|
||||
}
|
||||
|
||||
public boolean canAppliedToCode(String sourceCode) {
|
||||
return getMainProgrammingLanguage(sourceCode).orElse(null) instanceof JavaProgrammingLanguage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructuralUnit> getEntityClasses(String projectPath, String subDirectory, List<File> projectFiles) {
|
||||
return projectFiles.stream()
|
||||
@ -58,6 +64,12 @@ public class JavaIdentifier extends StructuralUnitIdentifier {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected Optional<ProgrammingLanguage> getMainProgrammingLanguage(String sourceCode) {
|
||||
return sourceCodeContainsClass(sourceCode)
|
||||
? Optional.of(getProgrammingLanguage())
|
||||
: Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructuralUnit> getBusinessLogicClasses() {
|
||||
return null;
|
||||
@ -91,16 +103,30 @@ public class JavaIdentifier extends StructuralUnitIdentifier {
|
||||
@Override
|
||||
public boolean isEntityClass(File file) {
|
||||
try {
|
||||
return file.getName().endsWith("java") && classContainsAnnotation(file, "@Entity");
|
||||
return file.getName().endsWith("java") && classContainsAnnotation(file, ENTITY_ANNOTATION);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean classContainsAnnotation(File file, String annotationDeclaration) throws FileNotFoundException {
|
||||
@Override
|
||||
public boolean isEntityClass(String sourceCode) {
|
||||
try {
|
||||
return classContainsAnnotation(sourceCode, ENTITY_ANNOTATION);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean classContainsAnnotation(File file, String annotationDeclaration) throws IOException {
|
||||
return classContainsAnnotation(new String(Files.readAllBytes(file.toPath())), annotationDeclaration);
|
||||
}
|
||||
|
||||
private boolean classContainsAnnotation(String sourceCode, String annotationDeclaration) {
|
||||
JavaParser parser = new JavaParser();
|
||||
ParseResult<CompilationUnit> parseResult = parser.parse(file);
|
||||
ParseResult<CompilationUnit> parseResult = parser.parse(sourceCode);
|
||||
if (parseResult.getResult().isPresent() && parseResult.getResult().get().findCompilationUnit().isPresent()) {
|
||||
return parseResult.getResult().get().getTypes().stream()
|
||||
.anyMatch(clazz -> clazz.getAnnotations().stream().anyMatch(annotation -> annotation.toString().startsWith(annotationDeclaration)));
|
||||
@ -108,6 +134,15 @@ public class JavaIdentifier extends StructuralUnitIdentifier {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean sourceCodeContainsClass(String sourceCode) {
|
||||
JavaParser parser = new JavaParser();
|
||||
ParseResult<CompilationUnit> parseResult = parser.parse(sourceCode);
|
||||
if (parseResult.getResult().isPresent() && parseResult.getResult().get().findCompilationUnit().isPresent()) {
|
||||
return parseResult.getResult().get().getTypes().stream().findAny().isPresent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSourceDirectory(List<File> rootDirectoryFiles) {
|
||||
return buildToolService.getProjectBuildTool(rootDirectoryFiles)
|
||||
|
@ -8,49 +8,53 @@ package ru.ulstu.extractor.heuristic.service;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.ulstu.extractor.heuristic.api.StructuralUnitIdentifier;
|
||||
import ru.ulstu.extractor.heuristic.model.StructuralUnit;
|
||||
import ru.ulstu.extractor.service.GitRepositoryService;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Service
|
||||
public class StructuralUnitService {
|
||||
private final GitRepositoryService gitRepositoryService;
|
||||
private final DirectoryService directoryService;
|
||||
private final List<StructuralUnitIdentifier> structuralUnitIdentifiers;
|
||||
|
||||
public StructuralUnitService(GitRepositoryService gitRepositoryService,
|
||||
DirectoryService directoryService,
|
||||
public StructuralUnitService(DirectoryService directoryService,
|
||||
List<StructuralUnitIdentifier> structuralUnitIdentifiers) {
|
||||
this.gitRepositoryService = gitRepositoryService;
|
||||
this.directoryService = directoryService;
|
||||
this.structuralUnitIdentifiers = structuralUnitIdentifiers;
|
||||
}
|
||||
|
||||
public List<StructuralUnit> getEntities(String repositoryUrl) throws IOException {
|
||||
File rootPath = gitRepositoryService.getProjectDirectoryFile(repositoryUrl);
|
||||
public List<StructuralUnit> getEntities(File rootPath) throws IOException {
|
||||
List<File> projectFiles = directoryService.getFilesRecursively(rootPath);
|
||||
List<File> rootProjectFiles = directoryService.getDirectoryFiles(rootPath.toPath());
|
||||
return getStructuralUnitIdentifier(
|
||||
structuralUnitIdentifier -> structuralUnitIdentifier.canAppliedToProject(
|
||||
rootPath.getPath(),
|
||||
projectFiles,
|
||||
rootProjectFiles)
|
||||
).getEntityClasses(rootPath.getPath(), projectFiles, rootProjectFiles);
|
||||
rootProjectFiles))
|
||||
.orElseThrow(() -> new RuntimeException("Identifier not found"))
|
||||
.getEntityClasses(rootPath.getPath(), projectFiles, rootProjectFiles);
|
||||
}
|
||||
|
||||
public boolean containsEntity(File projectFile) {
|
||||
return getStructuralUnitIdentifier(
|
||||
structuralUnitIdentifier -> structuralUnitIdentifier.canAppliedToFile(projectFile)
|
||||
).isEntityClass(projectFile);
|
||||
structuralUnitIdentifier -> structuralUnitIdentifier.canAppliedToFile(projectFile))
|
||||
.map(identifier -> identifier.isEntityClass(projectFile))
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
private StructuralUnitIdentifier getStructuralUnitIdentifier(Predicate<StructuralUnitIdentifier> predicate) {
|
||||
public boolean containsEntity(String sourceCode) {
|
||||
return getStructuralUnitIdentifier(
|
||||
structuralUnitIdentifier -> structuralUnitIdentifier.canAppliedToCode(sourceCode))
|
||||
.map(identifier -> identifier.isEntityClass(sourceCode))
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
private Optional<StructuralUnitIdentifier> getStructuralUnitIdentifier(Predicate<StructuralUnitIdentifier> predicate) {
|
||||
return structuralUnitIdentifiers.stream()
|
||||
.filter(predicate)
|
||||
.findAny()
|
||||
.orElseThrow(() -> new RuntimeException("Identifier not found"));
|
||||
.findAny();
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import org.hibernate.annotations.Fetch;
|
||||
@ -20,6 +25,9 @@ public class FileChange extends BaseEntity {
|
||||
@Transient
|
||||
private boolean added;
|
||||
|
||||
@Transient
|
||||
private boolean containsEntity;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "file_change_id", unique = true)
|
||||
@Fetch(FetchMode.SUBSELECT)
|
||||
@ -71,4 +79,12 @@ public class FileChange extends BaseEntity {
|
||||
public boolean isAdded() {
|
||||
return added;
|
||||
}
|
||||
|
||||
public boolean isContainsEntity() {
|
||||
return containsEntity;
|
||||
}
|
||||
|
||||
public void setContainsEntity(boolean containsEntity) {
|
||||
this.containsEntity = containsEntity;
|
||||
}
|
||||
}
|
||||
|
@ -12,10 +12,15 @@ import org.eclipse.jgit.api.ListBranchCommand;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.diff.DiffFormatter;
|
||||
import org.eclipse.jgit.internal.storage.file.FileRepository;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectLoader;
|
||||
import org.eclipse.jgit.lib.ObjectReader;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.ulstu.extractor.heuristic.service.StructuralUnitService;
|
||||
import ru.ulstu.extractor.model.Author;
|
||||
import ru.ulstu.extractor.model.Branch;
|
||||
import ru.ulstu.extractor.model.Commit;
|
||||
@ -28,6 +33,7 @@ import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
@ -44,6 +50,12 @@ public class GitRepositoryService {
|
||||
@Value("${extractor.custom-projects-dir}")
|
||||
private String customProjectsDir;
|
||||
|
||||
private final StructuralUnitService structuralUnitService;
|
||||
|
||||
public GitRepositoryService(StructuralUnitService structuralUnitService) {
|
||||
this.structuralUnitService = structuralUnitService;
|
||||
}
|
||||
|
||||
public List<Branch> getRemoteBranches(String url) throws GitAPIException, IOException {
|
||||
cloneOrUpdateRepo(url);
|
||||
Repository localRepo = new FileRepository(getProjectGitDirectory(url));
|
||||
@ -177,10 +189,10 @@ public class GitRepositoryService {
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error occurred during diff computation. Message: " + e.getMessage());
|
||||
}
|
||||
return parseOutputDiff(output);
|
||||
return parseOutputDiff(output, localRepo, laterCommit);
|
||||
}
|
||||
|
||||
private List<FileChange> parseOutputDiff(String output) {
|
||||
private List<FileChange> parseOutputDiff(String output, Repository repository, RevCommit commit) {
|
||||
List<FileChange> changes = new ArrayList<>();
|
||||
String[] strings = output.split("\n");
|
||||
FileChange fileChange = new FileChange();
|
||||
@ -191,6 +203,9 @@ public class GitRepositoryService {
|
||||
if (maybeFileName.isPresent()) {
|
||||
fileChange = new FileChange();
|
||||
fileChange.setFile(maybeFileName.get());
|
||||
fileChange.setContainsEntity(
|
||||
structuralUnitService.containsEntity(getContent(repository, commit, maybeFileName.get()))
|
||||
);
|
||||
/// вытащить другие изменения из коммита
|
||||
changes.add(fileChange);
|
||||
}
|
||||
@ -226,6 +241,22 @@ public class GitRepositoryService {
|
||||
return changes;
|
||||
}
|
||||
|
||||
private String getContent(Repository repository, RevCommit commit, String path) {
|
||||
try (TreeWalk treeWalk = TreeWalk.forPath(repository, path, commit.getTree())) {
|
||||
if (treeWalk != null) {
|
||||
ObjectId blobId = treeWalk.getObjectId(0);
|
||||
try (ObjectReader objectReader = repository.newObjectReader()) {
|
||||
ObjectLoader objectLoader = objectReader.open(blobId);
|
||||
byte[] bytes = objectLoader.getBytes();
|
||||
return new String(bytes, StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private Optional<String> getFileName(String commitString) {
|
||||
String startString = "diff --git a/";
|
||||
if (commitString.startsWith(startString)) {
|
||||
|
Loading…
Reference in New Issue
Block a user