WIP: страницы для правил #62
@ -35,6 +35,9 @@ compileJava {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
maven {
|
||||||
|
url="https://repository.ow2.org/nexus/content/repositories/public"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
@ -65,6 +68,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation group: 'com.ibm.icu', name: 'icu4j', version: '63.1'
|
implementation group: 'com.ibm.icu', name: 'icu4j', version: '63.1'
|
||||||
implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '5.9.0.202009080501-r'
|
implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '5.9.0.202009080501-r'
|
||||||
|
implementation group: 'com.fuzzylite', name: 'jfuzzylite', version: '6.0.1'
|
||||||
|
|
||||||
implementation group: 'org.webjars', name: 'jquery', version: '3.6.0'
|
implementation group: 'org.webjars', name: 'jquery', version: '3.6.0'
|
||||||
implementation group: 'org.webjars', name: 'bootstrap', version: '4.6.0'
|
implementation group: 'org.webjars', name: 'bootstrap', version: '4.6.0'
|
||||||
|
@ -2,12 +2,32 @@ package ru.ulstu.extractor;
|
|||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
import ru.ulstu.extractor.gitrepository.service.IndexService;
|
||||||
|
import ru.ulstu.extractor.rule.service.DbRuleService;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
|
@EnableAsync
|
||||||
public class GitExtractorApplication {
|
public class GitExtractorApplication {
|
||||||
|
private final IndexService indexService;
|
||||||
|
private final DbRuleService dbRuleService;
|
||||||
|
|
||||||
|
public GitExtractorApplication(IndexService indexService, DbRuleService dbRuleService) {
|
||||||
|
this.indexService = indexService;
|
||||||
|
this.dbRuleService = dbRuleService;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(GitExtractorApplication.class, args);
|
SpringApplication.run(GitExtractorApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
|
public void doSomethingAfterStartup() {
|
||||||
|
indexService.indexFailedBranchesOnStart();
|
||||||
|
//dbRuleService.generateRulesFromMarkup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
package ru.ulstu.extractor.assessment.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import ru.ulstu.extractor.assessment.model.FilterBranchForm;
|
||||||
|
import ru.ulstu.extractor.assessment.service.AssessmentService;
|
||||||
|
import ru.ulstu.extractor.branch.service.BranchService;
|
||||||
|
import springfox.documentation.annotations.ApiIgnore;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static ru.ulstu.extractor.core.Route.ASSESSMENTS;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@ApiIgnore
|
||||||
|
public class AssessmentController {
|
||||||
|
private final AssessmentService assessmentService;
|
||||||
|
private final BranchService branchService;
|
||||||
|
|
||||||
|
public AssessmentController(AssessmentService assessmentService,
|
||||||
|
BranchService branchService) {
|
||||||
|
this.assessmentService = assessmentService;
|
||||||
|
this.branchService = branchService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(ASSESSMENTS)
|
||||||
|
public String getAssessments(Model model, @RequestParam Optional<Integer> branchId) {
|
||||||
|
model.addAttribute("branches", branchService.findAllValid());
|
||||||
|
if (branchId.isPresent()) {
|
||||||
|
model.addAttribute("assessments", assessmentService.getAssessments(branchId.get()));
|
||||||
|
model.addAttribute("filterBranchForm", new FilterBranchForm(branchId.get()));
|
||||||
|
} else {
|
||||||
|
model.addAttribute("filterBranchForm", new FilterBranchForm());
|
||||||
|
}
|
||||||
|
return ASSESSMENTS;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package ru.ulstu.extractor.assessment.model;
|
||||||
|
|
||||||
|
import ru.ulstu.extractor.rule.model.DbRule;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeriesType;
|
||||||
|
|
||||||
|
public class Assessment {
|
||||||
|
private final String consequent;
|
||||||
|
private final TimeSeriesType firstAntecedent;
|
||||||
|
private final String firstAntecedentTendency;
|
||||||
|
private final TimeSeriesType secondAntecedent;
|
||||||
|
private final String secondAntecedentTendency;
|
||||||
|
private final Double degree;
|
||||||
|
|
||||||
|
public Assessment(DbRule dbRule, Double degree) {
|
||||||
|
this.consequent = dbRule.getConsequent();
|
||||||
|
this.firstAntecedent = dbRule.getFirstAntecedent();
|
||||||
|
this.firstAntecedentTendency = dbRule.getFirstAntecedentValue().getAntecedentValue();
|
||||||
|
this.secondAntecedent = dbRule.getSecondAntecedent();
|
||||||
|
this.secondAntecedentTendency = dbRule.getSecondAntecedentValue().getAntecedentValue();
|
||||||
|
this.degree = degree;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConsequent() {
|
||||||
|
return consequent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeriesType getFirstAntecedent() {
|
||||||
|
return firstAntecedent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstAntecedentTendency() {
|
||||||
|
return firstAntecedentTendency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeriesType getSecondAntecedent() {
|
||||||
|
return secondAntecedent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSecondAntecedentTendency() {
|
||||||
|
return secondAntecedentTendency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getDegree() {
|
||||||
|
return degree;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package ru.ulstu.extractor.assessment.model;
|
||||||
|
|
||||||
|
public class FilterBranchForm {
|
||||||
|
private Integer branchId;
|
||||||
|
|
||||||
|
public FilterBranchForm() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterBranchForm(Integer branchId) {
|
||||||
|
this.branchId = branchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getBranchId() {
|
||||||
|
return branchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBranchId(Integer branchId) {
|
||||||
|
this.branchId = branchId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package ru.ulstu.extractor.assessment.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.assessment.model.Assessment;
|
||||||
|
import ru.ulstu.extractor.rule.model.DbRule;
|
||||||
|
import ru.ulstu.extractor.rule.service.AntecedentValueService;
|
||||||
|
import ru.ulstu.extractor.rule.service.DbRuleService;
|
||||||
|
import ru.ulstu.extractor.rule.service.FuzzyInferenceService;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeries;
|
||||||
|
import ru.ulstu.extractor.ts.service.TimeSeriesService;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AssessmentService {
|
||||||
|
private final DbRuleService ruleService;
|
||||||
|
private final AntecedentValueService antecedentValueService;
|
||||||
|
private final TimeSeriesService timeSeriesService;
|
||||||
|
private final FuzzyInferenceService fuzzyInferenceService;
|
||||||
|
|
||||||
|
public AssessmentService(DbRuleService ruleService,
|
||||||
|
AntecedentValueService antecedentValueService,
|
||||||
|
TimeSeriesService timeSeriesService,
|
||||||
|
FuzzyInferenceService fuzzyInferenceService) {
|
||||||
|
this.ruleService = ruleService;
|
||||||
|
this.antecedentValueService = antecedentValueService;
|
||||||
|
this.timeSeriesService = timeSeriesService;
|
||||||
|
this.fuzzyInferenceService = fuzzyInferenceService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Assessment> getAssessments(Integer branchId) {
|
||||||
|
List<TimeSeries> timeSeries = timeSeriesService.getByBranch(branchId);
|
||||||
|
List<DbRule> dbRules = ruleService.getList();
|
||||||
|
Map<String, Double> variableValues = new HashMap<>();
|
||||||
|
timeSeries.forEach(ts -> variableValues.put(ts.getTimeSeriesType().name(), timeSeriesService.getLastTimeSeriesTendency(ts)));
|
||||||
|
return fuzzyInferenceService.getFuzzyInference(dbRules,
|
||||||
|
antecedentValueService.getList(),
|
||||||
|
variableValues)
|
||||||
|
.stream()
|
||||||
|
.sorted(Comparator.comparing(Assessment::getDegree).reversed())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
package ru.ulstu.extractor.model;
|
package ru.ulstu.extractor.author.model;
|
||||||
|
|
||||||
|
import ru.ulstu.extractor.core.BaseEntity;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
|
@ -1,15 +1,10 @@
|
|||||||
/*
|
package ru.ulstu.extractor.author.repository;
|
||||||
* 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.repository;
|
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import ru.ulstu.extractor.author.model.Author;
|
||||||
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
||||||
import ru.ulstu.extractor.model.Author;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -20,5 +15,5 @@ public interface AuthorRepository extends JpaRepository<Author, Integer> {
|
|||||||
List<Author> findByName(String name);
|
List<Author> findByName(String name);
|
||||||
|
|
||||||
@Query("SELECT DISTINCT a.name FROM Commit c, Branch b, Author a WHERE c.author = a AND c.branch = b AND (:branchId IS NULL OR b.id = :branchId) AND a.name IS NOT NULL AND a.name <> '' ORDER BY a.name")
|
@Query("SELECT DISTINCT a.name FROM Commit c, Branch b, Author a WHERE c.author = a AND c.branch = b AND (:branchId IS NULL OR b.id = :branchId) AND a.name IS NOT NULL AND a.name <> '' ORDER BY a.name")
|
||||||
List<String> findByBranchId(Integer branchId);
|
List<String> findByBranchId(@Param("branchId") Integer branchId);
|
||||||
}
|
}
|
@ -1,16 +1,12 @@
|
|||||||
/*
|
package ru.ulstu.extractor.author.service;
|
||||||
* 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.service;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.ulstu.extractor.model.Author;
|
import ru.ulstu.extractor.author.model.Author;
|
||||||
import ru.ulstu.extractor.repository.AuthorRepository;
|
import ru.ulstu.extractor.author.repository.AuthorRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@ -30,4 +26,8 @@ public class AuthorService {
|
|||||||
}
|
}
|
||||||
return newAuthor.get();
|
return newAuthor.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Author> findAll() {
|
||||||
|
return authorRepository.findAll();
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.branch.controller;
|
package ru.ulstu.extractor.branch.controller;
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
@ -10,11 +5,11 @@ import org.springframework.ui.Model;
|
|||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import ru.ulstu.extractor.branch.repository.BranchRepository;
|
import ru.ulstu.extractor.branch.repository.BranchRepository;
|
||||||
import ru.ulstu.extractor.gitrepository.GitRepositoryRepository;
|
import ru.ulstu.extractor.gitrepository.repository.GitRepositoryRepository;
|
||||||
import springfox.documentation.annotations.ApiIgnore;
|
import springfox.documentation.annotations.ApiIgnore;
|
||||||
|
|
||||||
import static ru.ulstu.extractor.controller.Route.DELETE_BRANCH;
|
import static ru.ulstu.extractor.core.Route.DELETE_BRANCH;
|
||||||
import static ru.ulstu.extractor.controller.Route.LIST_REPOSITORY_BRANCHES;
|
import static ru.ulstu.extractor.core.Route.LIST_REPOSITORY_BRANCHES;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ApiIgnore
|
@ApiIgnore
|
||||||
|
@ -1,27 +1,20 @@
|
|||||||
/*
|
|
||||||
* 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.branch.model;
|
package ru.ulstu.extractor.branch.model;
|
||||||
|
|
||||||
import org.hibernate.annotations.Fetch;
|
import org.hibernate.annotations.Fetch;
|
||||||
import org.hibernate.annotations.FetchMode;
|
import org.hibernate.annotations.FetchMode;
|
||||||
|
import ru.ulstu.extractor.commit.model.Commit;
|
||||||
|
import ru.ulstu.extractor.core.BaseEntity;
|
||||||
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
||||||
import ru.ulstu.extractor.model.BaseEntity;
|
|
||||||
import ru.ulstu.extractor.model.Commit;
|
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.*;
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.FetchType;
|
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static ru.ulstu.extractor.branch.model.IndexingStatus.EMPTY;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Branch extends BaseEntity {
|
public class Branch extends BaseEntity {
|
||||||
|
public static Integer GENERATED_BRANCH_ID = 1;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@ -32,6 +25,9 @@ public class Branch extends BaseEntity {
|
|||||||
@Fetch(FetchMode.SUBSELECT)
|
@Fetch(FetchMode.SUBSELECT)
|
||||||
private List<Commit> commits = new ArrayList<>();
|
private List<Commit> commits = new ArrayList<>();
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private IndexingStatus indexingStatus = EMPTY;
|
||||||
|
|
||||||
public Branch() {
|
public Branch() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,4 +63,12 @@ public class Branch extends BaseEntity {
|
|||||||
public void setCommits(List<Commit> commits) {
|
public void setCommits(List<Commit> commits) {
|
||||||
this.commits = commits;
|
this.commits = commits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IndexingStatus getIndexingStatus() {
|
||||||
|
return indexingStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndexingStatus(IndexingStatus indexingStatus) {
|
||||||
|
this.indexingStatus = indexingStatus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
package ru.ulstu.extractor.branch.model;
|
||||||
|
|
||||||
|
public enum IndexingStatus {
|
||||||
|
EMPTY, INDEXING, ERROR, FINISHED
|
||||||
|
}
|
@ -5,17 +5,23 @@ import org.springframework.data.domain.Pageable;
|
|||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import ru.ulstu.extractor.branch.model.Branch;
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
|
import ru.ulstu.extractor.branch.model.IndexingStatus;
|
||||||
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface BranchRepository extends JpaRepository<Branch, Integer> {
|
public interface BranchRepository extends JpaRepository<Branch, Integer> {
|
||||||
Branch findByGitRepositoryAndName(GitRepository gitRepository, String name);
|
Branch findByGitRepositoryAndName(GitRepository gitRepository, String name);
|
||||||
|
|
||||||
|
Optional<Branch> findByGitRepository_UrlAndName(String repositoryUrl, String name);
|
||||||
|
|
||||||
@Query("select count(c) from Commit c LEFT JOIN c.branch b LEFT JOIN GitRepository r where r.id = ?1 AND b.name = ?2")
|
@Query("select count(c) from Commit c LEFT JOIN c.branch b LEFT JOIN GitRepository r where r.id = ?1 AND b.name = ?2")
|
||||||
int getCommitsCount(Integer repositoryId, String name);
|
int getCommitsCount(Integer repositoryId, String name);
|
||||||
|
|
||||||
List<Branch> findByGitRepositoryId(Integer repositoryId);
|
List<Branch> findByGitRepositoryId(Integer repositoryId);
|
||||||
|
|
||||||
Page<Branch> findByGitRepository(GitRepository gitRepository, Pageable pageable);
|
Page<Branch> findByGitRepository(GitRepository gitRepository, Pageable pageable);
|
||||||
|
|
||||||
|
List<Branch> findAllByIndexingStatus(IndexingStatus indexingStatus);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.branch.service;
|
package ru.ulstu.extractor.branch.service;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -10,13 +5,16 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import ru.ulstu.extractor.branch.model.Branch;
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
|
import ru.ulstu.extractor.branch.model.IndexingStatus;
|
||||||
import ru.ulstu.extractor.branch.repository.BranchRepository;
|
import ru.ulstu.extractor.branch.repository.BranchRepository;
|
||||||
|
import ru.ulstu.extractor.commit.model.Commit;
|
||||||
import ru.ulstu.extractor.commit.service.CommitService;
|
import ru.ulstu.extractor.commit.service.CommitService;
|
||||||
|
import ru.ulstu.extractor.core.BaseEntity;
|
||||||
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
||||||
import ru.ulstu.extractor.model.BaseEntity;
|
import ru.ulstu.extractor.ts.service.TimeSeriesService;
|
||||||
import ru.ulstu.extractor.model.Commit;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@ -24,16 +22,25 @@ public class BranchService {
|
|||||||
private final static Logger LOG = LoggerFactory.getLogger(BranchService.class);
|
private final static Logger LOG = LoggerFactory.getLogger(BranchService.class);
|
||||||
private final BranchRepository branchRepository;
|
private final BranchRepository branchRepository;
|
||||||
private final CommitService commitService;
|
private final CommitService commitService;
|
||||||
|
private final TimeSeriesService timeSeriesService;
|
||||||
|
|
||||||
public BranchService(BranchRepository branchRepository,
|
public BranchService(BranchRepository branchRepository,
|
||||||
CommitService commitService) {
|
CommitService commitService,
|
||||||
|
TimeSeriesService timeSeriesService) {
|
||||||
this.branchRepository = branchRepository;
|
this.branchRepository = branchRepository;
|
||||||
this.commitService = commitService;
|
this.commitService = commitService;
|
||||||
|
this.timeSeriesService = timeSeriesService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Branch save(Branch branch) {
|
||||||
|
return branchRepository.save(branch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public Branch save(Branch branch, List<Commit> commits) {
|
public Branch save(Branch branch, List<Commit> commits) {
|
||||||
LOG.debug("Start save {} branch with {} commits ", branch.getName(), commits.size());
|
LOG.debug("Start save {} branch with {} commits ", branch.getName(), commits.size());
|
||||||
|
LOG.debug("Current branch contains {} commits ", branch.getCommits().size());
|
||||||
List<Integer> commitsToRemoveIds = branch.getCommits().stream().map(BaseEntity::getId).collect(Collectors.toList());
|
List<Integer> commitsToRemoveIds = branch.getCommits().stream().map(BaseEntity::getId).collect(Collectors.toList());
|
||||||
branch.setCommits(commitService.save(commits));
|
branch.setCommits(commitService.save(commits));
|
||||||
LOG.debug("Save branch {} ", branch.getName());
|
LOG.debug("Save branch {} ", branch.getName());
|
||||||
@ -43,19 +50,47 @@ public class BranchService {
|
|||||||
return branch;
|
return branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
public Branch addCommits(Branch branch, List<Commit> commits) {
|
public Branch addCommits(Branch branch, List<Commit> commits) {
|
||||||
LOG.debug("Start add commits to {} branch with {} commits ", branch.getName(), commits.size());
|
LOG.debug("Start add commits to {} branch with {} commits ", branch.getName(), commits.size());
|
||||||
commitService.save(commits);
|
branch.getCommits().addAll(commitService.save(commits));
|
||||||
LOG.debug("Save branch {} ", branch.getName());
|
LOG.debug("Save branch {} ", branch.getName());
|
||||||
commitService.updateBranchId(commits, branch.getId());
|
return save(branch);
|
||||||
return branch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Branch findByRepositoryAndName(GitRepository gitRepository, String branchName) {
|
public Branch findByRepositoryAndName(GitRepository gitRepository, String branchName) {
|
||||||
return branchRepository.findByGitRepositoryAndName(gitRepository, branchName);
|
return branchRepository.findByGitRepositoryAndName(gitRepository, branchName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Branch findByRepositoryAndNameOrCreate(GitRepository gitRepository, String branchName) {
|
||||||
|
Branch branch = branchRepository.findByGitRepositoryAndName(gitRepository, branchName);
|
||||||
|
return branch == null
|
||||||
|
? branchRepository.save(new Branch(gitRepository, branchName))
|
||||||
|
: branch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Branch> findByBranchId(Integer branchId) {
|
||||||
|
return branchRepository.findById(branchId);
|
||||||
|
}
|
||||||
|
|
||||||
public List<Branch> findAll() {
|
public List<Branch> findAll() {
|
||||||
return branchRepository.findAll();
|
return branchRepository.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Branch> findAllByIndexingStatus(IndexingStatus indexingStatus) {
|
||||||
|
return branchRepository.findAllByIndexingStatus(indexingStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Branch updateStatus(Branch branch, IndexingStatus indexingStatus) {
|
||||||
|
branch.setIndexingStatus(indexingStatus);
|
||||||
|
return branchRepository.save(branch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Branch> findAllValid() {
|
||||||
|
return findAll()
|
||||||
|
.stream()
|
||||||
|
//.filter(timeSeriesService::isBranchContainsAllTimeSeries)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
/*
|
package ru.ulstu.extractor.commit.model;
|
||||||
* 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;
|
import org.hibernate.annotations.Fetch;
|
||||||
import org.hibernate.annotations.FetchMode;
|
import org.hibernate.annotations.FetchMode;
|
||||||
|
import ru.ulstu.extractor.author.model.Author;
|
||||||
import ru.ulstu.extractor.branch.model.Branch;
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
|
import ru.ulstu.extractor.core.BaseEntity;
|
||||||
|
import ru.ulstu.extractor.gitrepository.model.FileChange;
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.commit.repository;
|
package ru.ulstu.extractor.commit.repository;
|
||||||
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@ -10,12 +5,12 @@ import org.springframework.data.domain.Pageable;
|
|||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import ru.ulstu.extractor.commit.model.Commit;
|
||||||
import ru.ulstu.extractor.commit.model.CommitAuthorStatistic;
|
import ru.ulstu.extractor.commit.model.CommitAuthorStatistic;
|
||||||
import ru.ulstu.extractor.commit.model.CommitEntityStatistic;
|
import ru.ulstu.extractor.commit.model.CommitEntityStatistic;
|
||||||
import ru.ulstu.extractor.commit.model.CommitTimeStatistic;
|
import ru.ulstu.extractor.commit.model.CommitTimeStatistic;
|
||||||
import ru.ulstu.extractor.commit.model.CommitUrlStatistic;
|
import ru.ulstu.extractor.commit.model.CommitUrlStatistic;
|
||||||
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
||||||
import ru.ulstu.extractor.model.Commit;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -1,15 +1,10 @@
|
|||||||
/*
|
|
||||||
* 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.commit.service;
|
package ru.ulstu.extractor.commit.service;
|
||||||
|
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.author.service.AuthorService;
|
||||||
|
import ru.ulstu.extractor.commit.model.Commit;
|
||||||
import ru.ulstu.extractor.commit.repository.CommitRepository;
|
import ru.ulstu.extractor.commit.repository.CommitRepository;
|
||||||
import ru.ulstu.extractor.model.Commit;
|
|
||||||
import ru.ulstu.extractor.service.AuthorService;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -44,14 +39,6 @@ public class CommitService {
|
|||||||
jdbcTemplate.update("DELETE FROM commit where branch_id is null");
|
jdbcTemplate.update("DELETE FROM commit where branch_id is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateBranchId(List<Commit> commits, Integer branchId) {
|
|
||||||
List<String> commitIds = commits.stream().map(c -> c.getId().toString()).collect(Collectors.toList());
|
|
||||||
String updateQuery = "update commit set branch_id = ? where id in (%s)";
|
|
||||||
updateQuery = String.format(updateQuery, String.join(",", commitIds));
|
|
||||||
jdbcTemplate.update(updateQuery, branchId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public List<Commit> findByRepositoryIdAndName(Integer repositoryId, String branchName) {
|
public List<Commit> findByRepositoryIdAndName(Integer repositoryId, String branchName) {
|
||||||
return commitRepository.findByRepositoryIdAndBranchName(repositoryId, branchName);
|
return commitRepository.findByRepositoryIdAndBranchName(repositoryId, branchName);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.config;
|
package ru.ulstu.extractor.config;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -11,12 +6,9 @@ import org.springframework.http.HttpStatus;
|
|||||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
|
||||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||||
import springfox.documentation.annotations.ApiIgnore;
|
import springfox.documentation.annotations.ApiIgnore;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
@ControllerAdvice
|
@ControllerAdvice
|
||||||
@ApiIgnore
|
@ApiIgnore
|
||||||
class GlobalDefaultExceptionHandler {
|
class GlobalDefaultExceptionHandler {
|
||||||
@ -24,15 +16,15 @@ class GlobalDefaultExceptionHandler {
|
|||||||
public static final String DEFAULT_ERROR_VIEW = "error";
|
public static final String DEFAULT_ERROR_VIEW = "error";
|
||||||
|
|
||||||
|
|
||||||
@ExceptionHandler(value = Exception.class)
|
// @ExceptionHandler(value = Exception.class)
|
||||||
public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) {
|
// public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) {
|
||||||
LOG.warn(e.getMessage());
|
// LOG.warn(e.getMessage());
|
||||||
ModelAndView mav = new ModelAndView();
|
// ModelAndView mav = new ModelAndView();
|
||||||
mav.addObject("exception", e);
|
// mav.addObject("exception", e);
|
||||||
mav.addObject("url", req.getRequestURL());
|
// mav.addObject("url", req.getRequestURL());
|
||||||
mav.setViewName(DEFAULT_ERROR_VIEW);
|
// mav.setViewName(DEFAULT_ERROR_VIEW);
|
||||||
return mav;
|
// return mav;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@ExceptionHandler(NoHandlerFoundException.class)
|
@ExceptionHandler(NoHandlerFoundException.class)
|
||||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.config;
|
package ru.ulstu.extractor.config;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@ -10,15 +5,13 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
|
|||||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
import static ru.ulstu.extractor.controller.Route.LIST_INDEXED_REPOSITORIES;
|
import static ru.ulstu.extractor.core.Route.LIST_INDEXED_REPOSITORIES;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class MvcConfiguration implements WebMvcConfigurer {
|
public class MvcConfiguration implements WebMvcConfigurer {
|
||||||
@Override
|
@Override
|
||||||
public void addViewControllers(ViewControllerRegistry registry) {
|
public void addViewControllers(ViewControllerRegistry registry) {
|
||||||
registry.addViewController("/{articlename:\\w+}");
|
|
||||||
registry.addRedirectViewController("/", LIST_INDEXED_REPOSITORIES);
|
registry.addRedirectViewController("/", LIST_INDEXED_REPOSITORIES);
|
||||||
registry.addRedirectViewController("/default", "/home");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ru.ulstu.extractor.model;
|
package ru.ulstu.extractor.core;
|
||||||
|
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
@ -8,7 +8,7 @@ import javax.persistence.Version;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
public abstract class BaseEntity implements Serializable, Comparable {
|
public abstract class BaseEntity implements Serializable, Comparable<BaseEntity> {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.TABLE)
|
@GeneratedValue(strategy = GenerationType.TABLE)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
@ -49,10 +49,10 @@ public abstract class BaseEntity implements Serializable, Comparable {
|
|||||||
}
|
}
|
||||||
BaseEntity other = (BaseEntity) obj;
|
BaseEntity other = (BaseEntity) obj;
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
if (other.id != null) {
|
if (other.getId() != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!id.equals(other.id)) {
|
} else if (!id.equals(other.getId())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -75,8 +75,8 @@ public abstract class BaseEntity implements Serializable, Comparable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(Object o) {
|
public int compareTo(BaseEntity o) {
|
||||||
return id != null ? id.compareTo(((BaseEntity) o).getId()) : -1;
|
return id != null ? id.compareTo(o.getId()) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
@ -1,4 +1,4 @@
|
|||||||
package ru.ulstu.extractor.model;
|
package ru.ulstu.extractor.core;
|
||||||
|
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
@ -1,9 +1,4 @@
|
|||||||
/*
|
package ru.ulstu.extractor.core;
|
||||||
* 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.controller;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -13,9 +8,17 @@ public class Route {
|
|||||||
public static final String DELETE_INDEXED_REPOSITORY = "deleteRepository";
|
public static final String DELETE_INDEXED_REPOSITORY = "deleteRepository";
|
||||||
public static final String LIST_REPOSITORY_BRANCHES = "listBranches";
|
public static final String LIST_REPOSITORY_BRANCHES = "listBranches";
|
||||||
public static final String DELETE_BRANCH = "deleteBranch";
|
public static final String DELETE_BRANCH = "deleteBranch";
|
||||||
|
public static final String REINDEX_BRANCH = "reindexBranch";
|
||||||
public static final String INDEXING_NEW_REPOSITORY = "indexNewRepository";
|
public static final String INDEXING_NEW_REPOSITORY = "indexNewRepository";
|
||||||
public static final String FILTER_COMMITS = "filterCommits";
|
public static final String FILTER_COMMITS = "filterCommits";
|
||||||
public static final String STATISTIC = "statistic";
|
public static final String STATISTIC = "statistic";
|
||||||
|
public static final String LIST_RULE = "listRules";
|
||||||
|
public static final String ADD_RULE = "addRule";
|
||||||
|
public static final String ASSESSMENTS = "assessments";
|
||||||
|
public static final String DELETE_RULE = "deleteRule";
|
||||||
|
public static final String ADD_MARKUP = "addMarkup";
|
||||||
|
|
||||||
|
public static final String GENERATION = "generation";
|
||||||
|
|
||||||
public static String getLIST_INDEXED_REPOSITORIES() {
|
public static String getLIST_INDEXED_REPOSITORIES() {
|
||||||
return LIST_INDEXED_REPOSITORIES;
|
return LIST_INDEXED_REPOSITORIES;
|
||||||
@ -36,4 +39,16 @@ public class Route {
|
|||||||
public static String getSTATISTIC() {
|
public static String getSTATISTIC() {
|
||||||
return STATISTIC;
|
return STATISTIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getASSESSMENTS() {
|
||||||
|
return ASSESSMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getADD_MARKUP() {
|
||||||
|
return ADD_MARKUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getGENERATION() {
|
||||||
|
return GENERATION;
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package ru.ulstu.extractor.generation.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import ru.ulstu.extractor.generation.model.GenerationForm;
|
||||||
|
import ru.ulstu.extractor.generation.service.GenerationService;
|
||||||
|
import springfox.documentation.annotations.ApiIgnore;
|
||||||
|
|
||||||
|
import static ru.ulstu.extractor.core.Route.GENERATION;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@ApiIgnore
|
||||||
|
public class GenerationController {
|
||||||
|
private final GenerationService generationService;
|
||||||
|
|
||||||
|
public GenerationController(GenerationService generationService) {
|
||||||
|
this.generationService = generationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(GENERATION)
|
||||||
|
public String getGenerationsPage(Model model) {
|
||||||
|
model.addAttribute("generationForm", new GenerationForm());
|
||||||
|
return GENERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(GENERATION)
|
||||||
|
public String setGenerationParams(Model model, @ModelAttribute GenerationForm generationForm) {
|
||||||
|
model.addAttribute("generationForm", generationForm);
|
||||||
|
generationService.generate(generationForm);
|
||||||
|
return GENERATION;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package ru.ulstu.extractor.generation.model;
|
||||||
|
|
||||||
|
public class GenerationForm {
|
||||||
|
private int tsLength;
|
||||||
|
private double min;
|
||||||
|
private double max;
|
||||||
|
private double base;
|
||||||
|
private double baseTendency;
|
||||||
|
private double tendencyDynamic;
|
||||||
|
private double randomWeight;
|
||||||
|
|
||||||
|
public int getTsLength() {
|
||||||
|
return tsLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTsLength(int tsLength) {
|
||||||
|
this.tsLength = tsLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMin() {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMin(double min) {
|
||||||
|
this.min = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMax() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMax(double max) {
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBase() {
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBase(double base) {
|
||||||
|
this.base = base;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBaseTendency() {
|
||||||
|
return baseTendency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBaseTendency(double baseTendency) {
|
||||||
|
this.baseTendency = baseTendency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getTendencyDynamic() {
|
||||||
|
return tendencyDynamic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTendencyDynamic(double tendencyDynamic) {
|
||||||
|
this.tendencyDynamic = tendencyDynamic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getRandomWeight() {
|
||||||
|
return randomWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRandomWeight(double randomWeight) {
|
||||||
|
this.randomWeight = randomWeight;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package ru.ulstu.extractor.generation.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
|
import ru.ulstu.extractor.branch.service.BranchService;
|
||||||
|
import ru.ulstu.extractor.generation.model.GenerationForm;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeriesType;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeriesValue;
|
||||||
|
import ru.ulstu.extractor.ts.service.TimeSeriesService;
|
||||||
|
import ru.ulstu.extractor.ts.util.DateUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class GenerationService {
|
||||||
|
private final TimeSeriesService timeSeriesService;
|
||||||
|
private final BranchService branchService;
|
||||||
|
|
||||||
|
public GenerationService(TimeSeriesService timeSeriesService,
|
||||||
|
BranchService branchService) {
|
||||||
|
this.timeSeriesService = timeSeriesService;
|
||||||
|
this.branchService = branchService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generate(GenerationForm generationForm) {
|
||||||
|
Branch branch = branchService.findByBranchId(Branch.GENERATED_BRANCH_ID).orElseThrow();
|
||||||
|
Date startDate = DateUtils.addDays(-generationForm.getTsLength());
|
||||||
|
Arrays.stream(TimeSeriesType.values()).forEach(tsType -> {
|
||||||
|
List<TimeSeriesValue> tsValues = new ArrayList<>();
|
||||||
|
for (int i = 0; i < generationForm.getTsLength(); i++) {
|
||||||
|
tsValues.add(new TimeSeriesValue(DateUtils.addDays(startDate, i),
|
||||||
|
getNextAdditiveValue(tsValues, generationForm)));
|
||||||
|
}
|
||||||
|
final String tsName = "Генерированный " + tsType.getDescription();
|
||||||
|
timeSeriesService.save(tsName, branch, tsType, tsValues);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getNextAdditiveValue(List<TimeSeriesValue> timeSeriesValues, GenerationForm generationForm) {
|
||||||
|
double newValue;
|
||||||
|
int maxTryCount = 10;
|
||||||
|
do {
|
||||||
|
double oneStepDiff = generationForm.getRandomWeight() * (Math.random() - 0.5) * (generationForm.getMax() - generationForm.getMin()) / (generationForm.getTsLength() + 10);
|
||||||
|
if (timeSeriesValues.isEmpty()) {
|
||||||
|
if (generationForm.getBaseTendency() > 0) {
|
||||||
|
newValue = 0.1 * (generationForm.getRandomWeight() > 0.0 ? oneStepDiff : 1.0) * (generationForm.getMax() - generationForm.getMin());
|
||||||
|
} else if (generationForm.getBaseTendency() < 0) {
|
||||||
|
newValue = generationForm.getMax() - 0.1 * (generationForm.getRandomWeight() > 0.0 ? oneStepDiff : 1.0) * (generationForm.getMax() - generationForm.getMin());
|
||||||
|
} else {
|
||||||
|
newValue = generationForm.getBase();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newValue = timeSeriesValues.get(timeSeriesValues.size() - 1).getValue()
|
||||||
|
+ (generationForm.getRandomWeight() > 0.0 ? oneStepDiff : 1.0) * generationForm.getBaseTendency()
|
||||||
|
* ((generationForm.getMax() - generationForm.getMin()) / (generationForm.getTsLength() + 10))
|
||||||
|
* generationForm.getTendencyDynamic();
|
||||||
|
}
|
||||||
|
maxTryCount--;
|
||||||
|
} while (((newValue <= generationForm.getMin())
|
||||||
|
|| (newValue >= generationForm.getMax()))
|
||||||
|
&& (maxTryCount > 0));
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,4 @@
|
|||||||
/*
|
package ru.ulstu.extractor.gitrepository.controler;
|
||||||
* 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.controller;
|
|
||||||
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
@ -11,10 +6,10 @@ import org.springframework.ui.Model;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import ru.ulstu.extractor.model.Commit;
|
import ru.ulstu.extractor.commit.model.Commit;
|
||||||
import ru.ulstu.extractor.model.OffsetablePageRequest;
|
import ru.ulstu.extractor.core.OffsetablePageRequest;
|
||||||
import ru.ulstu.extractor.model.mvc.FilterForm;
|
import ru.ulstu.extractor.gitrepository.model.FilterForm;
|
||||||
import ru.ulstu.extractor.service.FilteringService;
|
import ru.ulstu.extractor.gitrepository.service.FilteringService;
|
||||||
import springfox.documentation.annotations.ApiIgnore;
|
import springfox.documentation.annotations.ApiIgnore;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -22,7 +17,7 @@ import java.util.Optional;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import static ru.ulstu.extractor.controller.Route.FILTER_COMMITS;
|
import static ru.ulstu.extractor.core.Route.FILTER_COMMITS;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ApiIgnore
|
@ApiIgnore
|
@ -1,9 +1,4 @@
|
|||||||
/*
|
package ru.ulstu.extractor.gitrepository.controler;
|
||||||
* 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.controller;
|
|
||||||
|
|
||||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -14,19 +9,24 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
import ru.ulstu.extractor.branch.model.Branch;
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
import ru.ulstu.extractor.gitrepository.GitRepositoryService;
|
import ru.ulstu.extractor.branch.model.IndexingStatus;
|
||||||
import ru.ulstu.extractor.model.mvc.FilterForm;
|
import ru.ulstu.extractor.branch.service.BranchService;
|
||||||
import ru.ulstu.extractor.model.mvc.RepoForm;
|
import ru.ulstu.extractor.gitrepository.model.FilterForm;
|
||||||
import ru.ulstu.extractor.service.IndexService;
|
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
||||||
|
import ru.ulstu.extractor.gitrepository.model.RepoForm;
|
||||||
|
import ru.ulstu.extractor.gitrepository.service.GitRepositoryService;
|
||||||
|
import ru.ulstu.extractor.gitrepository.service.IndexService;
|
||||||
import springfox.documentation.annotations.ApiIgnore;
|
import springfox.documentation.annotations.ApiIgnore;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static ru.ulstu.extractor.controller.Route.FILTER_COMMITS;
|
import static ru.ulstu.extractor.core.Route.INDEXING_NEW_REPOSITORY;
|
||||||
import static ru.ulstu.extractor.controller.Route.INDEXING_NEW_REPOSITORY;
|
import static ru.ulstu.extractor.core.Route.LIST_REPOSITORY_BRANCHES;
|
||||||
|
import static ru.ulstu.extractor.core.Route.REINDEX_BRANCH;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ApiIgnore
|
@ApiIgnore
|
||||||
@ -34,11 +34,14 @@ public class GitIndexingController {
|
|||||||
private final static Logger LOG = LoggerFactory.getLogger(GitIndexingController.class);
|
private final static Logger LOG = LoggerFactory.getLogger(GitIndexingController.class);
|
||||||
private final GitRepositoryService gitRepositoryService;
|
private final GitRepositoryService gitRepositoryService;
|
||||||
private final IndexService indexService;
|
private final IndexService indexService;
|
||||||
|
private final BranchService branchService;
|
||||||
|
|
||||||
public GitIndexingController(GitRepositoryService gitRepositoryService,
|
public GitIndexingController(GitRepositoryService gitRepositoryService,
|
||||||
IndexService indexService) {
|
IndexService indexService,
|
||||||
|
BranchService branchService) {
|
||||||
this.gitRepositoryService = gitRepositoryService;
|
this.gitRepositoryService = gitRepositoryService;
|
||||||
this.indexService = indexService;
|
this.indexService = indexService;
|
||||||
|
this.branchService = branchService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(INDEXING_NEW_REPOSITORY)
|
@GetMapping(INDEXING_NEW_REPOSITORY)
|
||||||
@ -64,16 +67,36 @@ public class GitIndexingController {
|
|||||||
if (repoForm.getBranch() == null) {
|
if (repoForm.getBranch() == null) {
|
||||||
return INDEXING_NEW_REPOSITORY;
|
return INDEXING_NEW_REPOSITORY;
|
||||||
} else {
|
} else {
|
||||||
|
GitRepository gitRepository = gitRepositoryService.findByUrlOrCreate(repoForm.getRepo());
|
||||||
|
Branch branch = branchService.findByRepositoryAndNameOrCreate(gitRepository, repoForm.getBranch());
|
||||||
|
branch = branchService.updateStatus(branch, IndexingStatus.INDEXING);
|
||||||
try {
|
try {
|
||||||
indexService.index(repoForm.getRepo(), repoForm.getBranch());
|
indexService.index(gitRepository, branch);
|
||||||
} catch (IOException | GitAPIException ex) {
|
} catch (IOException | GitAPIException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
model.addAttribute("error", ex.getMessage());
|
model.addAttribute("error", ex.getMessage());
|
||||||
return INDEXING_NEW_REPOSITORY;
|
return INDEXING_NEW_REPOSITORY;
|
||||||
}
|
}
|
||||||
redirectAttributes.addAttribute("repositoryUrl", repoForm.getRepo());
|
redirectAttributes.addAttribute("repositoryId", branch.getGitRepository().getId());
|
||||||
redirectAttributes.addAttribute("branchName", repoForm.getBranch());
|
return "redirect:/" + LIST_REPOSITORY_BRANCHES;
|
||||||
return "redirect:/" + FILTER_COMMITS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping(REINDEX_BRANCH)
|
||||||
|
public String reindexBranch(Model model,
|
||||||
|
RedirectAttributes redirectAttributes,
|
||||||
|
@RequestParam Integer branchId) {
|
||||||
|
|
||||||
|
Branch branch = branchService.findByBranchId(branchId).orElseThrow(() -> new RuntimeException("Ветка не найдена по id"));
|
||||||
|
branch = branchService.updateStatus(branch, IndexingStatus.INDEXING);
|
||||||
|
try {
|
||||||
|
indexService.index(branchId);
|
||||||
|
} catch (IOException | GitAPIException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
model.addAttribute("error", ex.getMessage());
|
||||||
|
return INDEXING_NEW_REPOSITORY;
|
||||||
|
}
|
||||||
|
redirectAttributes.addAttribute("repositoryId", branch.getGitRepository().getId());
|
||||||
|
return "redirect:/" + LIST_REPOSITORY_BRANCHES;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,9 +1,4 @@
|
|||||||
/*
|
package ru.ulstu.extractor.gitrepository.controler;
|
||||||
* 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.controller;
|
|
||||||
|
|
||||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -12,16 +7,16 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import ru.ulstu.extractor.gitrepository.GitRepositoryService;
|
import ru.ulstu.extractor.commit.model.Commit;
|
||||||
import ru.ulstu.extractor.model.Commit;
|
import ru.ulstu.extractor.gitrepository.service.GitRepositoryService;
|
||||||
import ru.ulstu.extractor.service.IndexService;
|
import ru.ulstu.extractor.gitrepository.service.IndexService;
|
||||||
import ru.ulstu.extractor.util.HttpUtils;
|
import ru.ulstu.extractor.util.HttpUtils;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static ru.ulstu.extractor.controller.RepoController.URL;
|
import static ru.ulstu.extractor.gitrepository.controler.RepoController.URL;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(URL)
|
@RequestMapping(URL)
|
@ -1,19 +1,17 @@
|
|||||||
/*
|
package ru.ulstu.extractor.gitrepository.controler;
|
||||||
* 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.controller;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import ru.ulstu.extractor.gitrepository.GitRepositoryRepository;
|
import ru.ulstu.extractor.gitrepository.repository.GitRepositoryRepository;
|
||||||
import springfox.documentation.annotations.ApiIgnore;
|
import springfox.documentation.annotations.ApiIgnore;
|
||||||
|
|
||||||
import static ru.ulstu.extractor.controller.Route.DELETE_INDEXED_REPOSITORY;
|
import java.util.stream.Collectors;
|
||||||
import static ru.ulstu.extractor.controller.Route.LIST_INDEXED_REPOSITORIES;
|
|
||||||
|
import static ru.ulstu.extractor.core.Route.DELETE_INDEXED_REPOSITORY;
|
||||||
|
import static ru.ulstu.extractor.core.Route.LIST_INDEXED_REPOSITORIES;
|
||||||
|
import static ru.ulstu.extractor.gitrepository.model.GitRepository.GENERATED_REPOSITORY_ID;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ApiIgnore
|
@ApiIgnore
|
||||||
@ -26,7 +24,10 @@ public class RepositoryController {
|
|||||||
|
|
||||||
@GetMapping(LIST_INDEXED_REPOSITORIES)
|
@GetMapping(LIST_INDEXED_REPOSITORIES)
|
||||||
public String indexNewRepo(Model model) {
|
public String indexNewRepo(Model model) {
|
||||||
model.addAttribute("repositories", gitRepositoryRepository.findAll());
|
model.addAttribute("repositories", gitRepositoryRepository.findAll()
|
||||||
|
.stream()
|
||||||
|
.filter(r -> !r.getId().equals(GENERATED_REPOSITORY_ID))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
return LIST_INDEXED_REPOSITORIES;
|
return LIST_INDEXED_REPOSITORIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,7 +35,10 @@ public class RepositoryController {
|
|||||||
public String deleteRepo(Model model,
|
public String deleteRepo(Model model,
|
||||||
@RequestParam Integer id) {
|
@RequestParam Integer id) {
|
||||||
gitRepositoryRepository.deleteById(id);
|
gitRepositoryRepository.deleteById(id);
|
||||||
model.addAttribute("repositories", gitRepositoryRepository.findAll());
|
model.addAttribute("repositories", gitRepositoryRepository.findAll()
|
||||||
|
.stream()
|
||||||
|
.filter(r -> !r.getId().equals(GENERATED_REPOSITORY_ID))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
return "redirect:/" + LIST_INDEXED_REPOSITORIES;
|
return "redirect:/" + LIST_INDEXED_REPOSITORIES;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,4 @@
|
|||||||
/*
|
package ru.ulstu.extractor.gitrepository.controler;
|
||||||
* 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.controller;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
@ -11,15 +6,16 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import ru.ulstu.extractor.branch.service.BranchService;
|
import ru.ulstu.extractor.branch.service.BranchService;
|
||||||
import ru.ulstu.extractor.commit.repository.CommitRepository;
|
import ru.ulstu.extractor.commit.repository.CommitRepository;
|
||||||
import ru.ulstu.extractor.model.mvc.FilterForm;
|
import ru.ulstu.extractor.gitrepository.model.FilterForm;
|
||||||
import ru.ulstu.extractor.service.FilteringService;
|
import ru.ulstu.extractor.gitrepository.service.FilteringService;
|
||||||
import springfox.documentation.annotations.ApiIgnore;
|
import springfox.documentation.annotations.ApiIgnore;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static ru.ulstu.extractor.controller.Route.STATISTIC;
|
import static ru.ulstu.extractor.branch.model.Branch.GENERATED_BRANCH_ID;
|
||||||
|
import static ru.ulstu.extractor.core.Route.STATISTIC;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ApiIgnore
|
@ApiIgnore
|
||||||
@ -65,7 +61,9 @@ public class StatisticController {
|
|||||||
filterForm.setEntity(entity.orElse(null));
|
filterForm.setEntity(entity.orElse(null));
|
||||||
model.addAttribute("filterForm", filterForm);
|
model.addAttribute("filterForm", filterForm);
|
||||||
model.addAttribute("entityPresent", filteringService.getEntityPresent());
|
model.addAttribute("entityPresent", filteringService.getEntityPresent());
|
||||||
model.addAttribute("branches", branchService.findAll());
|
model.addAttribute("branches", branchService.findAll().stream()
|
||||||
|
.filter(r -> !r.getId().equals(GENERATED_BRANCH_ID))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
model.addAttribute("authors", filteringService.getRepositoryAuthors(branchId.orElse(null)));
|
model.addAttribute("authors", filteringService.getRepositoryAuthors(branchId.orElse(null)));
|
||||||
return STATISTIC;
|
return STATISTIC;
|
||||||
}
|
}
|
@ -1,12 +1,8 @@
|
|||||||
/*
|
package ru.ulstu.extractor.gitrepository.model;
|
||||||
* 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;
|
import org.hibernate.annotations.Fetch;
|
||||||
import org.hibernate.annotations.FetchMode;
|
import org.hibernate.annotations.FetchMode;
|
||||||
|
import ru.ulstu.extractor.core.BaseEntity;
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
@ -1,12 +1,7 @@
|
|||||||
/*
|
package ru.ulstu.extractor.gitrepository.model;
|
||||||
* 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.mvc;
|
|
||||||
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import ru.ulstu.extractor.model.Commit;
|
import ru.ulstu.extractor.commit.model.Commit;
|
||||||
|
|
||||||
public class FilterForm {
|
public class FilterForm {
|
||||||
private String filter;
|
private String filter;
|
@ -1,18 +1,23 @@
|
|||||||
package ru.ulstu.extractor.gitrepository.model;
|
package ru.ulstu.extractor.gitrepository.model;
|
||||||
|
|
||||||
import ru.ulstu.extractor.model.BaseEntity;
|
import ru.ulstu.extractor.core.BaseEntity;
|
||||||
|
import ru.ulstu.extractor.util.StringUtils;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class GitRepository extends BaseEntity {
|
public class GitRepository extends BaseEntity {
|
||||||
|
|
||||||
|
public static Integer GENERATED_REPOSITORY_ID = 1;
|
||||||
private String url;
|
private String url;
|
||||||
|
private String repositoryId;
|
||||||
|
|
||||||
public GitRepository() {
|
public GitRepository() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public GitRepository(String repositoryUrl) {
|
public GitRepository(String repositoryUrl, String repositoryId) {
|
||||||
url = repositoryUrl;
|
this.url = repositoryUrl;
|
||||||
|
this.repositoryId = repositoryId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
@ -22,4 +27,15 @@ public class GitRepository extends BaseEntity {
|
|||||||
public void setUrl(String url) {
|
public void setUrl(String url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRepositoryId() {
|
||||||
|
return repositoryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
int lastDelimiterIndex = url.lastIndexOf("/");
|
||||||
|
return StringUtils.removeDotGit((lastDelimiterIndex > 0 && lastDelimiterIndex < url.length())
|
||||||
|
? url.substring(lastDelimiterIndex + 1)
|
||||||
|
: url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
/*
|
package ru.ulstu.extractor.gitrepository.model;
|
||||||
* 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 ru.ulstu.extractor.core.BaseEntity;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
@ -12,8 +9,8 @@ public class LineChange extends BaseEntity {
|
|||||||
|
|
||||||
private Boolean added = false;
|
private Boolean added = false;
|
||||||
private Boolean removed = false;
|
private Boolean removed = false;
|
||||||
private String lineFrom;
|
private String lineFrom = "";
|
||||||
private String lineTo;
|
private String lineTo = "";
|
||||||
|
|
||||||
public LineChange() {
|
public LineChange() {
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package ru.ulstu.extractor.model.mvc;
|
package ru.ulstu.extractor.gitrepository.model;
|
||||||
|
|
||||||
public class RepoForm {
|
public class RepoForm {
|
||||||
private String repo;
|
private String repo;
|
@ -1,4 +1,4 @@
|
|||||||
package ru.ulstu.extractor.gitrepository;
|
package ru.ulstu.extractor.gitrepository.repository;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
@ -1,18 +1,13 @@
|
|||||||
/*
|
package ru.ulstu.extractor.gitrepository.service;
|
||||||
* 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.service;
|
|
||||||
|
|
||||||
import com.sun.istack.NotNull;
|
import com.sun.istack.NotNull;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.author.repository.AuthorRepository;
|
||||||
|
import ru.ulstu.extractor.commit.model.Commit;
|
||||||
import ru.ulstu.extractor.commit.repository.CommitRepository;
|
import ru.ulstu.extractor.commit.repository.CommitRepository;
|
||||||
import ru.ulstu.extractor.gitrepository.GitRepositoryRepository;
|
import ru.ulstu.extractor.gitrepository.repository.GitRepositoryRepository;
|
||||||
import ru.ulstu.extractor.model.Commit;
|
|
||||||
import ru.ulstu.extractor.repository.AuthorRepository;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
@ -0,0 +1,17 @@
|
|||||||
|
package ru.ulstu.extractor.gitrepository.service;
|
||||||
|
|
||||||
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
|
|
||||||
|
public interface GitApi {
|
||||||
|
Integer getBranchesCount(Branch branch);
|
||||||
|
|
||||||
|
Integer getStarsCount(Branch branch);
|
||||||
|
|
||||||
|
Integer getOpenIssuesCount(Branch branch);
|
||||||
|
|
||||||
|
String getFormattedUrl(Branch branch, String template);
|
||||||
|
|
||||||
|
Integer getAuthorsCompletedIssues(Branch branch);
|
||||||
|
|
||||||
|
String getRepositoryId(String repositoryUrl);
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package ru.ulstu.extractor.gitrepository.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
|
import ru.ulstu.extractor.http.HttpService;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class GitAtheneApi implements GitApi {
|
||||||
|
private final HttpService httpService;
|
||||||
|
private static final String BRANCHES_COUNT_URL = "%s/api/v1/repos/%s/%s/branches";
|
||||||
|
private static final String STARS_COUNT_URL = "%s/api/v1/repos/%s/%s";
|
||||||
|
private static final String OPEN_ISSUES_URL = "%s/api/v1/repos/%s/%s/issues?state=open";
|
||||||
|
private static final String COMPLETED_ISSUES_URL = "%s/api/v1/repos/%s/%s/issues?state=closed";
|
||||||
|
|
||||||
|
public GitAtheneApi(HttpService httpService) {
|
||||||
|
this.httpService = httpService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getBranchesCount(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, BRANCHES_COUNT_URL))
|
||||||
|
.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getStarsCount(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, STARS_COUNT_URL))
|
||||||
|
.getJSONObject(0)
|
||||||
|
.getInt("stars_count");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getOpenIssuesCount(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, OPEN_ISSUES_URL))
|
||||||
|
.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFormattedUrl(Branch branch, String template) {
|
||||||
|
String[] urlParts = branch.getGitRepository().getUrl().split("/");
|
||||||
|
return String.format(template, urlParts[0] + "/" + urlParts[1] + "/" + urlParts[2], urlParts[3], urlParts[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getAuthorsCompletedIssues(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, COMPLETED_ISSUES_URL))
|
||||||
|
.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRepositoryId(String repositoryUrl) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package ru.ulstu.extractor.gitrepository;
|
package ru.ulstu.extractor.gitrepository.service;
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.eclipse.jgit.api.CreateBranchCommand;
|
import org.eclipse.jgit.api.CreateBranchCommand;
|
||||||
@ -15,19 +15,22 @@ import org.eclipse.jgit.treewalk.TreeWalk;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.author.model.Author;
|
||||||
import ru.ulstu.extractor.branch.model.Branch;
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
|
import ru.ulstu.extractor.commit.model.Commit;
|
||||||
|
import ru.ulstu.extractor.gitrepository.model.FileChange;
|
||||||
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
||||||
|
import ru.ulstu.extractor.gitrepository.model.LineChange;
|
||||||
|
import ru.ulstu.extractor.gitrepository.repository.GitRepositoryRepository;
|
||||||
import ru.ulstu.extractor.heuristic.model.BusinessLogicUnit;
|
import ru.ulstu.extractor.heuristic.model.BusinessLogicUnit;
|
||||||
import ru.ulstu.extractor.heuristic.model.EntityUnit;
|
import ru.ulstu.extractor.heuristic.model.EntityUnit;
|
||||||
import ru.ulstu.extractor.heuristic.model.ResourceUnit;
|
import ru.ulstu.extractor.heuristic.model.ResourceUnit;
|
||||||
import ru.ulstu.extractor.heuristic.service.StructuralUnitService;
|
import ru.ulstu.extractor.heuristic.service.StructuralUnitService;
|
||||||
import ru.ulstu.extractor.model.Author;
|
import ru.ulstu.extractor.util.StringUtils;
|
||||||
import ru.ulstu.extractor.model.Commit;
|
|
||||||
import ru.ulstu.extractor.model.FileChange;
|
|
||||||
import ru.ulstu.extractor.model.LineChange;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -40,7 +43,9 @@ import java.nio.file.Path;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
@ -52,19 +57,26 @@ import static org.apache.logging.log4j.util.Strings.isBlank;
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class GitRepositoryService {
|
public class GitRepositoryService {
|
||||||
private final static Logger LOG = LoggerFactory.getLogger(GitRepositoryService.class);
|
private final Map<String, Class<? extends GitApi>> gitApiServiceHolder = Map.of(
|
||||||
|
"git.athene.tech", GitAtheneApi.class,
|
||||||
|
"github.com", GithubApi.class,
|
||||||
|
"gitlab.com", GitlabApi.class);
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(GitRepositoryService.class);
|
||||||
private static final String BRANCH_PREFIX = "refs/remotes/origin/";
|
private static final String BRANCH_PREFIX = "refs/remotes/origin/";
|
||||||
@Value("${extractor.custom-projects-dir}")
|
@Value("${extractor.custom-projects-dir}")
|
||||||
private String customProjectsDir;
|
private String customProjectsDir;
|
||||||
private final ExecutorService executorService = Executors.newFixedThreadPool(4);
|
private final ExecutorService executorService = Executors.newFixedThreadPool(8);
|
||||||
private final ExecutorService executorServiceCommits = Executors.newFixedThreadPool(4);
|
private final ExecutorService executorServiceCommits = Executors.newFixedThreadPool(8);
|
||||||
private final StructuralUnitService structuralUnitService;
|
private final StructuralUnitService structuralUnitService;
|
||||||
private final GitRepositoryRepository gitRepositoryRepository;
|
private final GitRepositoryRepository gitRepositoryRepository;
|
||||||
|
private final ApplicationContext applicationContext;
|
||||||
|
|
||||||
public GitRepositoryService(StructuralUnitService structuralUnitService,
|
public GitRepositoryService(StructuralUnitService structuralUnitService,
|
||||||
GitRepositoryRepository gitRepositoryRepository) {
|
GitRepositoryRepository gitRepositoryRepository,
|
||||||
|
ApplicationContext applicationContext) {
|
||||||
this.structuralUnitService = structuralUnitService;
|
this.structuralUnitService = structuralUnitService;
|
||||||
this.gitRepositoryRepository = gitRepositoryRepository;
|
this.gitRepositoryRepository = gitRepositoryRepository;
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Branch> getRemoteBranches(String url) throws GitAPIException, IOException {
|
public List<Branch> getRemoteBranches(String url) throws GitAPIException, IOException {
|
||||||
@ -184,7 +196,6 @@ public class GitRepositoryService {
|
|||||||
return structuralUnitService.getResource(getProjectDirectoryFile(repositoryUrl));
|
return structuralUnitService.getResource(getProjectDirectoryFile(repositoryUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void remove(String repositoryUrl) throws IOException {
|
public void remove(String repositoryUrl) throws IOException {
|
||||||
FileUtils.deleteDirectory(getProjectDirectoryFile(repositoryUrl));
|
FileUtils.deleteDirectory(getProjectDirectoryFile(repositoryUrl));
|
||||||
}
|
}
|
||||||
@ -268,7 +279,7 @@ public class GitRepositoryService {
|
|||||||
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||||
DiffFormatter diffFormatter = new DiffFormatter(out);
|
DiffFormatter diffFormatter = new DiffFormatter(out);
|
||||||
diffFormatter.setRepository(localRepo);
|
diffFormatter.setRepository(localRepo);
|
||||||
diffFormatter.format(earlierCommit.getId(), laterCommit.getId());
|
diffFormatter.format(laterCommit.getId(), earlierCommit.getId());
|
||||||
output = out.toString();
|
output = out.toString();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("Error occurred during diff computation. Message: " + e.getMessage());
|
throw new RuntimeException("Error occurred during diff computation. Message: " + e.getMessage());
|
||||||
@ -279,66 +290,21 @@ public class GitRepositoryService {
|
|||||||
private List<FileChange> parseOutputDiff(String output, org.eclipse.jgit.lib.Repository repository, RevCommit commit) {
|
private List<FileChange> parseOutputDiff(String output, org.eclipse.jgit.lib.Repository repository, RevCommit commit) {
|
||||||
List<FileChange> changes = new ArrayList<>();
|
List<FileChange> changes = new ArrayList<>();
|
||||||
String[] strings = output.split("\n");
|
String[] strings = output.split("\n");
|
||||||
|
Map<String, List<String>> filesContent = getFilesContent(strings);
|
||||||
|
for (Map.Entry<String, List<String>> fileSterings : filesContent.entrySet()) {
|
||||||
FileChange fileChange = new FileChange();
|
FileChange fileChange = new FileChange();
|
||||||
int stringsLength = strings.length - 1;
|
fileChange.setFile(fileSterings.getKey());
|
||||||
for (int i = 0; i < strings.length; i++) {
|
Future<Boolean> futureEntity = executorService.submit(() -> structuralUnitService.containsEntity(getContent(repository, commit, fileSterings.getKey())));
|
||||||
while (i < stringsLength) {
|
Future<Boolean> futureBL = executorService.submit(() -> structuralUnitService.containsBusinessLogic(getContent(repository, commit, fileSterings.getKey())));
|
||||||
Optional<String> maybeFileName = getFileName(strings[i]);
|
|
||||||
if (maybeFileName.isPresent()) {
|
|
||||||
fileChange = new FileChange();
|
|
||||||
fileChange.setFile(maybeFileName.get());
|
|
||||||
Future<Boolean> futureEntity = executorService.submit(() -> structuralUnitService.containsEntity(getContent(repository, commit, maybeFileName.get())));
|
|
||||||
Future<Boolean> futureBL = executorService.submit(() -> structuralUnitService.containsBusinessLogic(getContent(repository, commit, maybeFileName.get())));
|
|
||||||
try {
|
try {
|
||||||
fileChange.setContainsBusinessLogic(futureBL.get());
|
fileChange.setContainsBusinessLogic(futureBL.get());
|
||||||
fileChange.setContainsEntity(futureEntity.get());
|
fileChange.setContainsEntity(futureEntity.get());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOG.warn(ex.getMessage());
|
LOG.warn(ex.getMessage());
|
||||||
}
|
}
|
||||||
/// вытащить другие изменения из коммита
|
fileChange = getChange(fileChange, fileSterings.getValue());
|
||||||
changes.add(fileChange);
|
changes.add(fileChange);
|
||||||
}
|
}
|
||||||
LineChange lineChange = new LineChange();
|
|
||||||
if (strings[i].startsWith("-")) {
|
|
||||||
while ((i < stringsLength) && strings[i].startsWith("-")) {
|
|
||||||
if (strings[i].startsWith("---")) {
|
|
||||||
i++;
|
|
||||||
} else {
|
|
||||||
if (lineChange.getLineFrom() == null) {
|
|
||||||
lineChange.setLineFrom(strings[i]);
|
|
||||||
i++;
|
|
||||||
} else {
|
|
||||||
lineChange.setLineFrom(lineChange.getLineFrom() + "\n" + strings[i]);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lineChange.setRemoved(true);
|
|
||||||
}
|
|
||||||
if (strings[i].startsWith("+")) {
|
|
||||||
while ((i < stringsLength) && strings[i].startsWith("+")) {
|
|
||||||
if (strings[i].startsWith("+++")) {
|
|
||||||
i++;
|
|
||||||
} else {
|
|
||||||
if (lineChange.getLineTo() == null) {
|
|
||||||
lineChange.setLineTo(strings[i]);
|
|
||||||
i++;
|
|
||||||
} else {
|
|
||||||
lineChange.setLineTo(lineChange.getLineTo() + "\n" + strings[i]);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lineChange.setAdded(true);
|
|
||||||
}
|
|
||||||
if ((lineChange.getLineTo() != null) || (lineChange.getLineFrom() != null)
|
|
||||||
|| ((lineChange.getLineTo() != null) && (lineChange.getLineFrom() != null))) {
|
|
||||||
fileChange.getLineChanges().add(lineChange);
|
|
||||||
} else {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,7 +333,99 @@ public class GitRepositoryService {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, List<String>> getFilesContent(String[] commitStrings) {
|
||||||
|
int i = 0;
|
||||||
|
Map<String, List<String>> result = new HashMap<>();
|
||||||
|
while (i < commitStrings.length) {
|
||||||
|
Optional<String> maybeFileName = getFileName(commitStrings[i]);
|
||||||
|
if (maybeFileName.isEmpty()) {
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
i = skipLinesForNextFile(commitStrings, i);
|
||||||
|
result.put(maybeFileName.get(), getFileContent(commitStrings, i));
|
||||||
|
i += getFileContent(commitStrings, i).size() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getFileContent(String[] commitsString, int i) {
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
while (i < commitsString.length && getFileName(commitsString[i]).isEmpty()) {
|
||||||
|
result.add(commitsString[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int skipLinesForNextFile(String[] commitStrings, int index) {
|
||||||
|
boolean isFilePrefixSkipped = false;
|
||||||
|
while (!isFilePrefixSkipped && (index < commitStrings.length)) {
|
||||||
|
if ((commitStrings[index].startsWith("diff --git a/"))
|
||||||
|
|| (commitStrings[index].startsWith("delete"))
|
||||||
|
|| (commitStrings[index].startsWith("new"))
|
||||||
|
|| (commitStrings[index].startsWith("index"))
|
||||||
|
|| (commitStrings[index].startsWith("@@"))
|
||||||
|
|| (commitStrings[index].startsWith("---"))
|
||||||
|
|| (commitStrings[index].startsWith("+++"))) {
|
||||||
|
index++;
|
||||||
|
} else {
|
||||||
|
isFilePrefixSkipped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileChange getChange(FileChange fileChange, List<String> fileContent) {
|
||||||
|
int i = 0;
|
||||||
|
int added = 0;
|
||||||
|
int removed = 0;
|
||||||
|
while (i < fileContent.size()) {
|
||||||
|
LineChange lineChange = new LineChange();
|
||||||
|
while ((i < fileContent.size()) && fileContent.get(i).startsWith("-")) {
|
||||||
|
lineChange.setRemoved(true);
|
||||||
|
lineChange.setLineFrom(lineChange.getLineFrom() + "\n" + fileContent.get(i).replaceFirst("\\-", ""));
|
||||||
|
removed++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while ((i < fileContent.size()) && fileContent.get(i).startsWith("+")) {
|
||||||
|
lineChange.setAdded(true);
|
||||||
|
lineChange.setLineTo(lineChange.getLineTo() + "\n" + fileContent.get(i).replaceFirst("\\+", ""));
|
||||||
|
added++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (!lineChange.getLineTo().isEmpty() || !lineChange.getLineFrom().isEmpty()) {
|
||||||
|
fileChange.getLineChanges().add(lineChange);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
fileChange.setRemoved(removed == fileContent.size());
|
||||||
|
fileChange.setAdded(added == fileContent.size());
|
||||||
|
return fileChange;
|
||||||
|
}
|
||||||
|
|
||||||
public Page<GitRepository> findAll(Pageable pageable) {
|
public Page<GitRepository> findAll(Pageable pageable) {
|
||||||
return gitRepositoryRepository.findAll(pageable);
|
return gitRepositoryRepository.findAll(pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GitRepository findById(Integer id) {
|
||||||
|
return gitRepositoryRepository.getOne(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GitRepository findByUrlOrCreate(String gitRepositoryUrl) {
|
||||||
|
GitRepository gitRepository = gitRepositoryRepository.findByUrl(gitRepositoryUrl);
|
||||||
|
|
||||||
|
return gitRepository == null
|
||||||
|
? gitRepositoryRepository.save(new GitRepository(gitRepositoryUrl,
|
||||||
|
applicationContext.getBean(getGitApiServiceClass(gitRepositoryUrl)).getRepositoryId(gitRepositoryUrl)))
|
||||||
|
: gitRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends GitApi> getGitApiServiceClass(Branch branch) {
|
||||||
|
return getGitApiServiceClass(branch.getGitRepository().getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends GitApi> getGitApiServiceClass(String url) {
|
||||||
|
return gitApiServiceHolder.get(StringUtils.getServerDomain(url));
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package ru.ulstu.extractor.gitrepository.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
|
import ru.ulstu.extractor.http.HttpService;
|
||||||
|
import ru.ulstu.extractor.util.StringUtils;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class GithubApi implements GitApi {
|
||||||
|
private final HttpService httpService;
|
||||||
|
private static final String BRANCHES_COUNT_URL = "https://api.github.com/repos/%s/%s/branches";
|
||||||
|
private static final String STARS_COUNT_URL = "https://api.github.com/repos/%s/%s";
|
||||||
|
private static final String OPEN_ISSUES_URL = "https://api.github.com/repos/%s/%s/issues?state=open";
|
||||||
|
private static final String AUTHOR_COMPLETED_ISSUES_URL = "https://api.github.com/repos/%s/%s/issues?state=open";
|
||||||
|
|
||||||
|
public GithubApi(HttpService httpService) {
|
||||||
|
this.httpService = httpService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getBranchesCount(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, BRANCHES_COUNT_URL))
|
||||||
|
.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getStarsCount(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, STARS_COUNT_URL))
|
||||||
|
.getJSONObject(0)
|
||||||
|
.getInt("watchers");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getOpenIssuesCount(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, OPEN_ISSUES_URL))
|
||||||
|
.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFormattedUrl(Branch branch, String template) {
|
||||||
|
String[] urlParts = branch.getGitRepository().getUrl().split("/");
|
||||||
|
return String.format(template, urlParts[3], StringUtils.removeDotGit(urlParts[4]));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getAuthorsCompletedIssues(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, AUTHOR_COMPLETED_ISSUES_URL))
|
||||||
|
.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRepositoryId(String repositoryUrl) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
package ru.ulstu.extractor.gitrepository.service;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
|
import ru.ulstu.extractor.http.HttpService;
|
||||||
|
|
||||||
|
import static ru.ulstu.extractor.util.StringUtils.getUrlParts;
|
||||||
|
import static ru.ulstu.extractor.util.StringUtils.removeDotGit;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class GitlabApi implements GitApi {
|
||||||
|
private final HttpService httpService;
|
||||||
|
private static final String BRANCHES_COUNT_URL = "%s/api/v4/projects/%s/repository/branches";
|
||||||
|
private final static String PROJECT_ID_URL = "https://gitlab.com/api/v4/users/%s/projects?search=%s";
|
||||||
|
private static final String PROJECT_INFO_URL = "%s/api/v4/projects/%s";
|
||||||
|
private static final String OPEN_ISSUES_URL = "%s/api/v4/projects/%s/issues?state=opened";
|
||||||
|
private static final String COMPLETED_ISSUES_URL = "%s/api/v4/projects/%s/issues?state=closed";
|
||||||
|
|
||||||
|
public GitlabApi(HttpService httpService) {
|
||||||
|
this.httpService = httpService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getBranchesCount(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, BRANCHES_COUNT_URL))
|
||||||
|
.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getStarsCount(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, PROJECT_INFO_URL))
|
||||||
|
.getJSONObject(0)
|
||||||
|
.getInt("star_count");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getOpenIssuesCount(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, OPEN_ISSUES_URL))
|
||||||
|
.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFormattedUrl(Branch branch, String template) {
|
||||||
|
String[] urlParts = getUrlParts(branch.getGitRepository().getUrl());
|
||||||
|
return String.format(template, urlParts[0] + "/" + urlParts[1] + "/" + urlParts[2], branch.getGitRepository().getRepositoryId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormattedUrlForProjectId(String repositoryUrl, String template) {
|
||||||
|
String[] urlParts = getUrlParts(repositoryUrl);
|
||||||
|
// получаем корректное название репозитория, gitlab всегда добавляет .git в конец
|
||||||
|
return String.format(template, urlParts[3], removeDotGit(urlParts[4]));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getAuthorsCompletedIssues(Branch branch) {
|
||||||
|
return httpService
|
||||||
|
.get(getFormattedUrl(branch, COMPLETED_ISSUES_URL))
|
||||||
|
.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRepositoryId(String repositoryUrl) {
|
||||||
|
JSONArray projects = httpService.get(getFormattedUrlForProjectId(repositoryUrl, PROJECT_ID_URL));
|
||||||
|
for (int i = 0; i < projects.length(); i++) {
|
||||||
|
if (projects.getJSONObject(i).get("name").equals(removeDotGit(getUrlParts(repositoryUrl)[4]))) {
|
||||||
|
return String.valueOf(projects.getJSONObject(i).getInt("id"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Id проекта не найден: " + repositoryUrl);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
package ru.ulstu.extractor.gitrepository.service;
|
||||||
|
|
||||||
|
import com.sun.istack.NotNull;
|
||||||
|
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
|
import ru.ulstu.extractor.branch.model.IndexingStatus;
|
||||||
|
import ru.ulstu.extractor.branch.service.BranchService;
|
||||||
|
import ru.ulstu.extractor.commit.model.Commit;
|
||||||
|
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
||||||
|
import ru.ulstu.extractor.ts.creator.db.DBTimeSeriesCreator;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class IndexService {
|
||||||
|
private final static Logger LOG = LoggerFactory.getLogger(IndexService.class);
|
||||||
|
private final static int COMMITS_PAGE_SIZE = 10;
|
||||||
|
private final GitRepositoryService gitRepositoryService;
|
||||||
|
private final BranchService branchService;
|
||||||
|
private final List<DBTimeSeriesCreator> timeSeriesCreators;
|
||||||
|
|
||||||
|
public IndexService(GitRepositoryService gitRepositoryService,
|
||||||
|
BranchService branchService,
|
||||||
|
List<DBTimeSeriesCreator> timeSeriesCreators) {
|
||||||
|
this.gitRepositoryService = gitRepositoryService;
|
||||||
|
this.branchService = branchService;
|
||||||
|
this.timeSeriesCreators = timeSeriesCreators;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Async
|
||||||
|
public void index(@NotNull Integer branchId) throws GitAPIException, IOException {
|
||||||
|
Branch branch = branchService.findByBranchId(branchId).orElseThrow(() -> new RuntimeException("Ветка репозитория не найдена по id"));
|
||||||
|
index(branch.getGitRepository(), branch);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Async
|
||||||
|
public void index(String gitRepositoryUrl, String branchName) throws GitAPIException, IOException {
|
||||||
|
GitRepository gitRepository = gitRepositoryService.findByUrlOrCreate(gitRepositoryUrl);
|
||||||
|
Branch branch = branchService.findByRepositoryAndNameOrCreate(gitRepository, branchName);
|
||||||
|
branch = branchService.updateStatus(branch, IndexingStatus.INDEXING);
|
||||||
|
index(gitRepository, branch);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Async
|
||||||
|
public void index(GitRepository gitRepository, Branch branch) throws GitAPIException, IOException {
|
||||||
|
branchService.save(branch, Collections.emptyList());
|
||||||
|
branch = branchService.updateStatus(branch, IndexingStatus.INDEXING);
|
||||||
|
int commitsFrom = 0;
|
||||||
|
int commitsTo = COMMITS_PAGE_SIZE;
|
||||||
|
List<Commit> commits = gitRepositoryService.getCommits(gitRepository.getUrl(), branch.getName(), commitsFrom, commitsTo, true);
|
||||||
|
while (!commits.isEmpty()) {
|
||||||
|
LOG.debug("{} commits loaded.", commits.size());
|
||||||
|
branchService.addCommits(branch, commits);
|
||||||
|
LOG.debug("{} commits successfully saved. {} {}", commits.size(), gitRepository.getUrl(), branch.getName());
|
||||||
|
commitsFrom += COMMITS_PAGE_SIZE;
|
||||||
|
commitsTo += COMMITS_PAGE_SIZE;
|
||||||
|
commits = gitRepositoryService.getCommits(gitRepository.getUrl(), branch.getName(), commitsFrom, commitsTo, false);
|
||||||
|
}
|
||||||
|
branch = branchService.findByBranchId(branch.getId()).orElseThrow(() -> new RuntimeException("Branch not found by id"));
|
||||||
|
final Branch branchForSave = branchService.updateStatus(branch, IndexingStatus.FINISHED);
|
||||||
|
timeSeriesCreators.forEach(tsCreator -> tsCreator.addTimeSeries(branchForSave));
|
||||||
|
LOG.debug("Complete indexing {} branch", branch.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Async
|
||||||
|
public void indexFailedBranchesOnStart() {
|
||||||
|
LOG.info("Старт проверки незавершенных задач для индексирований...");
|
||||||
|
|
||||||
|
List<Branch> failedBranches = branchService.findAllByIndexingStatus(IndexingStatus.INDEXING);
|
||||||
|
if (failedBranches.size() > 0) {
|
||||||
|
LOG.info("Найдено {} незавершенных задач для индексирования", failedBranches.size());
|
||||||
|
failedBranches.forEach(failedBranch -> {
|
||||||
|
try {
|
||||||
|
index(failedBranch.getId());
|
||||||
|
LOG.info("Завершено индексирование ветки {}", failedBranch.getName());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LOG.warn(ex.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
LOG.info("Завершено индексирование незавершенных задач");
|
||||||
|
} else {
|
||||||
|
LOG.info("Не найдено незавершенных веток для индексирования");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.api;
|
package ru.ulstu.extractor.heuristic.api;
|
||||||
|
|
||||||
import ru.ulstu.extractor.heuristic.component.BuildTool;
|
import ru.ulstu.extractor.heuristic.component.BuildTool;
|
||||||
@ -112,4 +107,6 @@ public abstract class StructuralUnitIdentifier {
|
|||||||
public abstract boolean isResourceClass(String sourceCode);
|
public abstract boolean isResourceClass(String sourceCode);
|
||||||
|
|
||||||
protected abstract boolean isResourceClass(File file);
|
protected abstract boolean isResourceClass(File file);
|
||||||
|
|
||||||
|
public abstract List<String> getClasses(String sourceCode);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.component;
|
package ru.ulstu.extractor.heuristic.component;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.component;
|
package ru.ulstu.extractor.heuristic.component;
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.component;
|
package ru.ulstu.extractor.heuristic.component;
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.component;
|
package ru.ulstu.extractor.heuristic.component;
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.component;
|
package ru.ulstu.extractor.heuristic.component;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.controller;
|
package ru.ulstu.extractor.heuristic.controller;
|
||||||
|
|
||||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||||
@ -11,7 +6,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import ru.ulstu.extractor.gitrepository.GitRepositoryService;
|
import ru.ulstu.extractor.gitrepository.service.GitRepositoryService;
|
||||||
import ru.ulstu.extractor.heuristic.model.BusinessLogicUnit;
|
import ru.ulstu.extractor.heuristic.model.BusinessLogicUnit;
|
||||||
import ru.ulstu.extractor.heuristic.model.EntityUnit;
|
import ru.ulstu.extractor.heuristic.model.EntityUnit;
|
||||||
import ru.ulstu.extractor.heuristic.model.ResourceUnit;
|
import ru.ulstu.extractor.heuristic.model.ResourceUnit;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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;
|
package ru.ulstu.extractor.heuristic.model;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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;
|
package ru.ulstu.extractor.heuristic.model;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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;
|
package ru.ulstu.extractor.heuristic.model;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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;
|
package ru.ulstu.extractor.heuristic.model;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.service;
|
package ru.ulstu.extractor.heuristic.service;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.service;
|
package ru.ulstu.extractor.heuristic.service;
|
||||||
|
|
||||||
import com.gargoylesoftware.htmlunit.WebClient;
|
import com.gargoylesoftware.htmlunit.WebClient;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.service;
|
package ru.ulstu.extractor.heuristic.service;
|
||||||
|
|
||||||
import com.sun.istack.NotNull;
|
import com.sun.istack.NotNull;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.service;
|
package ru.ulstu.extractor.heuristic.service;
|
||||||
|
|
||||||
import com.github.javaparser.JavaParser;
|
import com.github.javaparser.JavaParser;
|
||||||
@ -11,6 +6,7 @@ import com.github.javaparser.ast.CompilationUnit;
|
|||||||
import com.github.javaparser.ast.body.FieldDeclaration;
|
import com.github.javaparser.ast.body.FieldDeclaration;
|
||||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||||
import com.github.javaparser.ast.body.TypeDeclaration;
|
import com.github.javaparser.ast.body.TypeDeclaration;
|
||||||
|
import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.ulstu.extractor.heuristic.api.StructuralUnitIdentifier;
|
import ru.ulstu.extractor.heuristic.api.StructuralUnitIdentifier;
|
||||||
import ru.ulstu.extractor.heuristic.component.BuildTool;
|
import ru.ulstu.extractor.heuristic.component.BuildTool;
|
||||||
@ -24,6 +20,7 @@ import ru.ulstu.extractor.util.StringUtils;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -57,6 +54,9 @@ public class JavaIdentifier extends StructuralUnitIdentifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean canAppliedToCode(String sourceCode) {
|
public boolean canAppliedToCode(String sourceCode) {
|
||||||
|
if (sourceCode == null || sourceCode.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return getMainProgrammingLanguage(sourceCode).orElse(null) instanceof JavaProgrammingLanguage;
|
return getMainProgrammingLanguage(sourceCode).orElse(null) instanceof JavaProgrammingLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,12 +174,7 @@ public class JavaIdentifier extends StructuralUnitIdentifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean sourceCodeContainsClass(String sourceCode) {
|
private boolean sourceCodeContainsClass(String sourceCode) {
|
||||||
JavaParser parser = new JavaParser();
|
return getClasses(sourceCode).size() > 0;
|
||||||
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
|
@Override
|
||||||
@ -248,4 +243,14 @@ public class JavaIdentifier extends StructuralUnitIdentifier {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getClasses(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().map(NodeWithSimpleName::getNameAsString).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.service;
|
package ru.ulstu.extractor.heuristic.service;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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.service;
|
package ru.ulstu.extractor.heuristic.service;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package ru.ulstu.extractor.http;
|
package ru.ulstu.extractor.http;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -8,6 +9,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.web.reactive.function.BodyInserters;
|
import org.springframework.web.reactive.function.BodyInserters;
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@ -21,7 +23,9 @@ public class HttpService {
|
|||||||
|
|
||||||
public JSONObject post(String url, JSONObject postData) {
|
public JSONObject post(String url, JSONObject postData) {
|
||||||
log.debug("Service call: {}", url);
|
log.debug("Service call: {}", url);
|
||||||
JSONObject response = new JSONObject(Optional.ofNullable(client
|
JSONObject response = null;
|
||||||
|
try {
|
||||||
|
response = new JSONObject(Optional.ofNullable(client
|
||||||
.post()
|
.post()
|
||||||
.uri(url)
|
.uri(url)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
@ -29,8 +33,54 @@ public class HttpService {
|
|||||||
.accept(MediaType.APPLICATION_JSON)
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(String.class)
|
.bodyToMono(String.class)
|
||||||
.block()).orElse("{response:\"empty\"}"));
|
.toFuture().get()).orElse("{response:\"empty\"}"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return new JSONObject("{response:\"empty\"}");
|
||||||
|
}
|
||||||
log.debug("Service response: {}", response);
|
log.debug("Service response: {}", response);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONArray post(String url, JSONArray postData) {
|
||||||
|
log.debug("Service call: {}", url);
|
||||||
|
JSONArray response = null;
|
||||||
|
try {
|
||||||
|
response = new JSONArray(Optional.ofNullable(client
|
||||||
|
.post()
|
||||||
|
.uri(url)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.body(BodyInserters.fromValue(postData.toString()))
|
||||||
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(String.class)
|
||||||
|
.toFuture().get()).orElse("[{response:\"empty\"}]"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return new JSONArray("[{response:\"empty\"}]");
|
||||||
|
}
|
||||||
|
log.debug("Service response: {}", response);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray get(String url) {
|
||||||
|
log.debug("Service call: {}", url);
|
||||||
|
try {
|
||||||
|
String response = client
|
||||||
|
.get()
|
||||||
|
.uri(url)
|
||||||
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(String.class)
|
||||||
|
.timeout(Duration.ofMinutes(1))
|
||||||
|
.toFuture().get();
|
||||||
|
if (response.startsWith("[")) {
|
||||||
|
return new JSONArray(response);
|
||||||
|
} else {
|
||||||
|
JSONArray jsonArray = new JSONArray();
|
||||||
|
jsonArray.put(0, new JSONObject(response));
|
||||||
|
return jsonArray;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package ru.ulstu.extractor.http;
|
package ru.ulstu.extractor.http;
|
||||||
|
|
||||||
import ru.ulstu.extractor.model.TimeSeries;
|
import ru.ulstu.extractor.ts.model.TimeSeries;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package ru.ulstu.extractor.http;
|
package ru.ulstu.extractor.http;
|
||||||
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
import ru.ulstu.extractor.ts.model.TimeSeriesValue;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package ru.ulstu.extractor.http;
|
||||||
|
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeries;
|
||||||
|
|
||||||
|
public class SmoothingTimeSeries {
|
||||||
|
private JsonTimeSeries originalTimeSeries;
|
||||||
|
private String methodClassName;
|
||||||
|
|
||||||
|
public SmoothingTimeSeries(TimeSeries timeSeries) {
|
||||||
|
originalTimeSeries = new JsonTimeSeries(timeSeries);
|
||||||
|
this.methodClassName = "FTransform";
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonTimeSeries getOriginalTimeSeries() {
|
||||||
|
return originalTimeSeries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOriginalTimeSeries(JsonTimeSeries originalTimeSeries) {
|
||||||
|
this.originalTimeSeries = originalTimeSeries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMethodClassName() {
|
||||||
|
return methodClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMethodClassName(String methodClassName) {
|
||||||
|
this.methodClassName = methodClassName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package ru.ulstu.extractor.markup.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import ru.ulstu.extractor.branch.service.BranchService;
|
||||||
|
import ru.ulstu.extractor.core.Route;
|
||||||
|
import ru.ulstu.extractor.markup.model.MarkupForm;
|
||||||
|
import ru.ulstu.extractor.markup.model.TimeSeriesForMarkup;
|
||||||
|
import ru.ulstu.extractor.markup.service.MarkupService;
|
||||||
|
import ru.ulstu.extractor.ts.service.TimeSeriesService;
|
||||||
|
import springfox.documentation.annotations.ApiIgnore;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static ru.ulstu.extractor.branch.model.Branch.GENERATED_BRANCH_ID;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@ApiIgnore
|
||||||
|
public class TimeSeriesMarkupController {
|
||||||
|
private final TimeSeriesService timeSeriesService;
|
||||||
|
private final BranchService branchService;
|
||||||
|
private final MarkupService markupService;
|
||||||
|
|
||||||
|
public TimeSeriesMarkupController(TimeSeriesService timeSeriesService,
|
||||||
|
BranchService branchService,
|
||||||
|
MarkupService markupService) {
|
||||||
|
this.timeSeriesService = timeSeriesService;
|
||||||
|
this.branchService = branchService;
|
||||||
|
this.markupService = markupService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("time-series-markup")
|
||||||
|
public String markupTs(Model model) {
|
||||||
|
model.addAttribute("branches", branchService.findAllValid().stream()
|
||||||
|
.filter(r -> !r.getId().equals(GENERATED_BRANCH_ID))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
model.addAttribute("markupForm", new MarkupForm());
|
||||||
|
return "markup";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("time-series-markup")
|
||||||
|
public String filter(Model model, @ModelAttribute MarkupForm markupForm) {
|
||||||
|
model.addAttribute("branches", branchService.findAllValid().stream()
|
||||||
|
.filter(r -> !r.getId().equals(GENERATED_BRANCH_ID))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
if (markupForm != null && markupForm.getBranchId() != null) {
|
||||||
|
List<TimeSeriesForMarkup> tss = markupService.getTimeSeriesForMarkup(
|
||||||
|
timeSeriesService.getGroupedTendencies(
|
||||||
|
timeSeriesService.getByBranch(markupForm.getBranchId())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
MarkupForm markupFormWithTs = new MarkupForm(markupForm.getBranchId(), tss);
|
||||||
|
model.addAttribute("markupForm", markupFormWithTs);
|
||||||
|
} else {
|
||||||
|
model.addAttribute("markupForm", new MarkupForm());
|
||||||
|
}
|
||||||
|
return "markup";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(Route.ADD_MARKUP)
|
||||||
|
public String addMarkups(Model model, @ModelAttribute MarkupForm markupForm) {
|
||||||
|
model.addAttribute("branches", branchService.findAllValid().stream()
|
||||||
|
.filter(r -> !r.getId().equals(GENERATED_BRANCH_ID))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
if (markupForm != null && markupForm.getBranchId() != null) {
|
||||||
|
List<TimeSeriesForMarkup> tss = markupService.getTimeSeriesForMarkup(
|
||||||
|
timeSeriesService.getGroupedTendencies(
|
||||||
|
timeSeriesService.getByBranch(markupForm.getBranchId())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
MarkupForm markupFormWithTs = new MarkupForm(markupForm.getBranchId(), tss);
|
||||||
|
model.addAttribute("markupForm", markupFormWithTs);
|
||||||
|
if (markupForm.getTimeSeriesForMarkupList() != null
|
||||||
|
&& !markupForm.getTimeSeriesForMarkupList().isEmpty()) {
|
||||||
|
markupService.generateRules(markupForm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "markup";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package ru.ulstu.extractor.markup.model;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MarkupForm {
|
||||||
|
private List<TimeSeriesForMarkup> timeSeriesForMarkupList = new ArrayList<>();
|
||||||
|
private Integer branchId;
|
||||||
|
|
||||||
|
public MarkupForm() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public MarkupForm(Integer branchId, List<TimeSeriesForMarkup> tss) {
|
||||||
|
this.timeSeriesForMarkupList = tss;
|
||||||
|
this.branchId = branchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TimeSeriesForMarkup> getTimeSeriesForMarkupList() {
|
||||||
|
return timeSeriesForMarkupList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeSeriesForMarkupList(List<TimeSeriesForMarkup> timeSeriesForMarkupList) {
|
||||||
|
this.timeSeriesForMarkupList = timeSeriesForMarkupList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getBranchId() {
|
||||||
|
return branchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBranchId(Integer branchId) {
|
||||||
|
this.branchId = branchId;
|
||||||
|
}
|
||||||
|
}
|
31
src/main/java/ru/ulstu/extractor/markup/model/MarkupRow.java
Normal file
31
src/main/java/ru/ulstu/extractor/markup/model/MarkupRow.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package ru.ulstu.extractor.markup.model;
|
||||||
|
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeries;
|
||||||
|
|
||||||
|
public class MarkupRow {
|
||||||
|
private TimeSeries timeSeries;
|
||||||
|
private String markup;
|
||||||
|
|
||||||
|
public MarkupRow() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public MarkupRow(TimeSeries ts) {
|
||||||
|
this.timeSeries = ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeries getTimeSeries() {
|
||||||
|
return timeSeries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeSeries(TimeSeries timeSeries) {
|
||||||
|
this.timeSeries = timeSeries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMarkup() {
|
||||||
|
return markup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMarkup(String markup) {
|
||||||
|
this.markup = markup;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package ru.ulstu.extractor.markup.model;
|
||||||
|
|
||||||
|
import ru.ulstu.extractor.rule.model.AntecedentValue;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeries;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeriesType;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class TimeSeriesForMarkup {
|
||||||
|
//output
|
||||||
|
private Map<TimeSeries, AntecedentValue> timeSeriesTendencyMap = new HashMap<>();
|
||||||
|
private Date dateFrom;
|
||||||
|
private Date dateTo;
|
||||||
|
|
||||||
|
//input
|
||||||
|
private List<TimeSeriesType> timeSeriesTypes;
|
||||||
|
private List<AntecedentValue> antecedentValues;
|
||||||
|
private String markup;
|
||||||
|
|
||||||
|
public TimeSeriesForMarkup() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeriesForMarkup(TimeSeries ts1, AntecedentValue tendency1, TimeSeries ts2, AntecedentValue tendency2, Date dateFrom, Date dateTo) {
|
||||||
|
this.dateFrom = dateFrom;
|
||||||
|
this.dateTo = dateTo;
|
||||||
|
this.timeSeriesTendencyMap.put(ts1, tendency1);
|
||||||
|
this.timeSeriesTendencyMap.put(ts2, tendency2);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<TimeSeries, AntecedentValue> getTimeSeriesTendencyMap() {
|
||||||
|
return timeSeriesTendencyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDateFrom() {
|
||||||
|
return dateFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDateFrom(Date dateFrom) {
|
||||||
|
this.dateFrom = dateFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDateTo() {
|
||||||
|
return dateTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDateTo(Date dateTo) {
|
||||||
|
this.dateTo = dateTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMarkup() {
|
||||||
|
return markup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeSeriesTendencyMap(Map<TimeSeries, AntecedentValue> timeSeriesTendencyMap) {
|
||||||
|
this.timeSeriesTendencyMap = timeSeriesTendencyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMarkup(String markup) {
|
||||||
|
this.markup = markup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TimeSeriesType> getTimeSeriesTypes() {
|
||||||
|
return timeSeriesTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeSeriesTypes(List<TimeSeriesType> timeSeriesTypes) {
|
||||||
|
this.timeSeriesTypes = timeSeriesTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AntecedentValue> getAntecedentValues() {
|
||||||
|
return antecedentValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAntecedentValues(List<AntecedentValue> antecedentValues) {
|
||||||
|
this.antecedentValues = antecedentValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh() {
|
||||||
|
this.antecedentValues = new ArrayList<>(timeSeriesTendencyMap.values());
|
||||||
|
this.timeSeriesTypes = timeSeriesTendencyMap.keySet().stream().map(TimeSeries::getTimeSeriesType).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
package ru.ulstu.extractor.markup.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.markup.model.MarkupForm;
|
||||||
|
import ru.ulstu.extractor.markup.model.TimeSeriesForMarkup;
|
||||||
|
import ru.ulstu.extractor.rule.model.AntecedentValue;
|
||||||
|
import ru.ulstu.extractor.rule.service.AntecedentValueService;
|
||||||
|
import ru.ulstu.extractor.rule.service.DbRuleService;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeries;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeriesValue;
|
||||||
|
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class MarkupService {
|
||||||
|
private final DbRuleService dbRuleService;
|
||||||
|
private final AntecedentValueService antecedentValueService;
|
||||||
|
|
||||||
|
public MarkupService(DbRuleService dbRuleService,
|
||||||
|
AntecedentValueService antecedentValueService) {
|
||||||
|
this.dbRuleService = dbRuleService;
|
||||||
|
this.antecedentValueService = antecedentValueService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void generateRules(MarkupForm markupForm) {
|
||||||
|
markupForm.getTimeSeriesForMarkupList().forEach(markupRow -> {
|
||||||
|
for (int i = 0; i < markupRow.getTimeSeriesTypes().size(); i++) {
|
||||||
|
for (int j = i+1; j < markupRow.getTimeSeriesTypes().size(); j++) {
|
||||||
|
if (i != j) {
|
||||||
|
dbRuleService.saveRule(markupRow.getTimeSeriesTypes().get(i), markupRow.getAntecedentValues().get(i),
|
||||||
|
markupRow.getTimeSeriesTypes().get(j), markupRow.getAntecedentValues().get(j),
|
||||||
|
markupRow.getMarkup());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private AntecedentValue getAntecedent(Double diff) {
|
||||||
|
String antecedentValue;
|
||||||
|
if (diff < 0) {
|
||||||
|
antecedentValue = "спад";
|
||||||
|
} else if (diff > 0) {
|
||||||
|
antecedentValue = "рост";
|
||||||
|
} else {
|
||||||
|
antecedentValue = "стабильно";
|
||||||
|
}
|
||||||
|
return antecedentValueService.getByValue(antecedentValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<TimeSeriesForMarkup> getTimeSeriesForMarkup(List<TimeSeries> timeSeriesList) {
|
||||||
|
List<TimeSeriesForMarkup> tsForMarkup = new ArrayList<>();
|
||||||
|
for (int i = 0; i < timeSeriesList.size(); i++) {
|
||||||
|
TimeSeries ts1 = timeSeriesList.get(i);
|
||||||
|
for (int j = i + 1; j < timeSeriesList.size(); j++) {
|
||||||
|
TimeSeries ts2 = timeSeriesList.get(j);
|
||||||
|
List<TimeSeriesValue> values1 = ts1.getValues();
|
||||||
|
for (int k = 0; k < values1.size() - 1; k++) {
|
||||||
|
List<TimeSeriesValue> values2 = ts2.getValues();
|
||||||
|
for (int l = 0; l < values2.size() - 1; l++) {
|
||||||
|
if (values1.get(k).getDate().equals(values2.get(l).getDate())
|
||||||
|
&& values1.get(k + 1).getDate().equals(values2.get(l + 1).getDate())) {
|
||||||
|
final int index = k;
|
||||||
|
TimeSeriesForMarkup found = tsForMarkup
|
||||||
|
.stream()
|
||||||
|
.filter(m -> m.getDateFrom().equals(values1.get(index).getDate()) && m.getDateTo().equals(values1.get(index + 1).getDate()))
|
||||||
|
.findAny()
|
||||||
|
.orElse(null);
|
||||||
|
AntecedentValue antecedentValue1 = getAntecedent(values1.get(index + 1).getValue() - values1.get(index).getValue());
|
||||||
|
AntecedentValue antecedentValue2 = getAntecedent(values2.get(l + 1).getValue() - values2.get(l).getValue());
|
||||||
|
if (found == null) {
|
||||||
|
tsForMarkup.add(new TimeSeriesForMarkup(ts1, antecedentValue1, ts2, antecedentValue2, values1.get(index).getDate(), values1.get(index + 1).getDate()));
|
||||||
|
} else {
|
||||||
|
found.getTimeSeriesTendencyMap().put(ts1, antecedentValue1);
|
||||||
|
found.getTimeSeriesTendencyMap().put(ts2, antecedentValue2);
|
||||||
|
found.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tsForMarkup
|
||||||
|
.stream()
|
||||||
|
.sorted(Comparator.comparing(TimeSeriesForMarkup::getDateFrom))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@ -1,50 +0,0 @@
|
|||||||
package ru.ulstu.extractor.model;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.Fetch;
|
|
||||||
import org.hibernate.annotations.FetchMode;
|
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.FetchType;
|
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class TimeSeries extends BaseEntity {
|
|
||||||
private String name;
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "time_series_id")
|
|
||||||
@Fetch(FetchMode.SUBSELECT)
|
|
||||||
private List<TimeSeriesValue> values = new ArrayList<>();
|
|
||||||
|
|
||||||
public TimeSeries() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeSeries(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeSeries(String name, List<TimeSeriesValue> values) {
|
|
||||||
this.name = name;
|
|
||||||
this.values = values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TimeSeriesValue> getValues() {
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValues(List<TimeSeriesValue> values) {
|
|
||||||
this.values = values;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package ru.ulstu.extractor.repository;
|
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeries;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public interface TimeSeriesRepository extends JpaRepository<TimeSeries, Integer> {
|
|
||||||
Optional<TimeSeries> findByName(String name);
|
|
||||||
}
|
|
@ -0,0 +1,61 @@
|
|||||||
|
package ru.ulstu.extractor.rule.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
|
import ru.ulstu.extractor.rule.model.AddRuleForm;
|
||||||
|
import ru.ulstu.extractor.rule.service.AntecedentValueService;
|
||||||
|
import ru.ulstu.extractor.rule.service.DbRuleService;
|
||||||
|
import ru.ulstu.extractor.ts.service.TimeSeriesService;
|
||||||
|
import springfox.documentation.annotations.ApiIgnore;
|
||||||
|
|
||||||
|
import static ru.ulstu.extractor.core.Route.ADD_RULE;
|
||||||
|
import static ru.ulstu.extractor.core.Route.DELETE_RULE;
|
||||||
|
import static ru.ulstu.extractor.core.Route.LIST_RULE;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@ApiIgnore
|
||||||
|
public class RuleController {
|
||||||
|
private final DbRuleService ruleService;
|
||||||
|
private final AntecedentValueService antecedentValueService;
|
||||||
|
private final TimeSeriesService timeSeriesService;
|
||||||
|
|
||||||
|
public RuleController(DbRuleService dbRuleService,
|
||||||
|
AntecedentValueService antecedentValueService,
|
||||||
|
TimeSeriesService timeSeriesService) {
|
||||||
|
this.ruleService = dbRuleService;
|
||||||
|
this.antecedentValueService = antecedentValueService;
|
||||||
|
this.timeSeriesService = timeSeriesService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(LIST_RULE)
|
||||||
|
public String getList(Model model) {
|
||||||
|
model.addAttribute("rules", ruleService.getList());
|
||||||
|
return LIST_RULE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(ADD_RULE)
|
||||||
|
public String getAntecedent(Model model, @RequestParam(required = false) Integer ruleId) {
|
||||||
|
model.addAttribute("antecedentValues", antecedentValueService.getList());
|
||||||
|
model.addAttribute("antecedents", timeSeriesService.getAllTimeSeriesTypes());
|
||||||
|
model.addAttribute("addRuleForm", ruleService.getAddRuleFormOrDefault(ruleId));
|
||||||
|
return ADD_RULE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = ADD_RULE, method = RequestMethod.POST)
|
||||||
|
public String addRule(@ModelAttribute AddRuleForm ruleForm, Model model, RedirectAttributes redirectAttributes) {
|
||||||
|
ruleService.saveRule(ruleForm);
|
||||||
|
return "redirect:/" + LIST_RULE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(DELETE_RULE)
|
||||||
|
public String deleteRule(@RequestParam Integer id) {
|
||||||
|
ruleService.deleteById(id);
|
||||||
|
return "redirect:/" + LIST_RULE;
|
||||||
|
}
|
||||||
|
}
|
81
src/main/java/ru/ulstu/extractor/rule/model/AddRuleForm.java
Normal file
81
src/main/java/ru/ulstu/extractor/rule/model/AddRuleForm.java
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package ru.ulstu.extractor.rule.model;
|
||||||
|
|
||||||
|
public class AddRuleForm {
|
||||||
|
private Integer ruleId;
|
||||||
|
private Integer firstAntecedentValueId;
|
||||||
|
private String firstAntecedentId;
|
||||||
|
private Integer secondAntecedentValueId;
|
||||||
|
private String secondAntecedentId;
|
||||||
|
private String consequent;
|
||||||
|
|
||||||
|
public AddRuleForm() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddRuleForm(DbRule rule) {
|
||||||
|
this.ruleId = rule.getId();
|
||||||
|
this.firstAntecedentId = rule.getFirstAntecedent().name();
|
||||||
|
this.secondAntecedentId = rule.getSecondAntecedent().name();
|
||||||
|
this.firstAntecedentValueId = rule.getFirstAntecedentValue().getId();
|
||||||
|
this.secondAntecedentValueId = rule.getSecondAntecedentValue().getId();
|
||||||
|
this.consequent = rule.getConsequent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRuleId() {
|
||||||
|
return ruleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRuleId(Integer ruleId) {
|
||||||
|
this.ruleId = ruleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getFirstAntecedentValueId() {
|
||||||
|
return firstAntecedentValueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstAntecedentValueId(Integer firstAntecedentValueId) {
|
||||||
|
this.firstAntecedentValueId = firstAntecedentValueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstAntecedentId() {
|
||||||
|
return firstAntecedentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstAntecedentId(String firstAntecedentId) {
|
||||||
|
this.firstAntecedentId = firstAntecedentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSecondAntecedentValueId() {
|
||||||
|
return secondAntecedentValueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecondAntecedentValueId(Integer secondAntecedentValueId) {
|
||||||
|
this.secondAntecedentValueId = secondAntecedentValueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSecondAntecedentId() {
|
||||||
|
return secondAntecedentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecondAntecedentId(String secondAntecedentId) {
|
||||||
|
this.secondAntecedentId = secondAntecedentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConsequent() {
|
||||||
|
return consequent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConsequent(String consequent) {
|
||||||
|
this.consequent = consequent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AddRuleForm{" +
|
||||||
|
"firstAntecedentValueId=" + firstAntecedentValueId +
|
||||||
|
", firstAntecedentId=" + firstAntecedentId +
|
||||||
|
", secondAntecedentValueId=" + secondAntecedentValueId +
|
||||||
|
", secondAntecedentId=" + secondAntecedentId +
|
||||||
|
", consequent='" + consequent + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package ru.ulstu.extractor.rule.model;
|
||||||
|
|
||||||
|
import ru.ulstu.extractor.core.BaseEntity;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class AntecedentValue extends BaseEntity {
|
||||||
|
private String antecedentValue;
|
||||||
|
|
||||||
|
public AntecedentValue() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AntecedentValue(String antecedentValue) {
|
||||||
|
this.antecedentValue = antecedentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAntecedentValue() {
|
||||||
|
return antecedentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAntecedentValue(String antecedentValue) {
|
||||||
|
this.antecedentValue = antecedentValue;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package ru.ulstu.extractor.rule.model;
|
||||||
|
|
||||||
|
public class AssessmentException extends RuntimeException {
|
||||||
|
public AssessmentException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
83
src/main/java/ru/ulstu/extractor/rule/model/DbRule.java
Normal file
83
src/main/java/ru/ulstu/extractor/rule/model/DbRule.java
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package ru.ulstu.extractor.rule.model;
|
||||||
|
|
||||||
|
import ru.ulstu.extractor.core.BaseEntity;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeriesType;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "rule")
|
||||||
|
public class DbRule extends BaseEntity {
|
||||||
|
@ManyToOne
|
||||||
|
private AntecedentValue firstAntecedentValue;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private TimeSeriesType firstAntecedent;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private AntecedentValue secondAntecedentValue;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private TimeSeriesType secondAntecedent;
|
||||||
|
|
||||||
|
private String consequent;
|
||||||
|
|
||||||
|
public DbRule() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbRule(AntecedentValue firstAntecedentValue,
|
||||||
|
TimeSeriesType firstAntecedent,
|
||||||
|
AntecedentValue secondAntecedentValue,
|
||||||
|
TimeSeriesType secondAntecedent,
|
||||||
|
String consequent) {
|
||||||
|
this.firstAntecedentValue = firstAntecedentValue;
|
||||||
|
this.firstAntecedent = firstAntecedent;
|
||||||
|
this.secondAntecedentValue = secondAntecedentValue;
|
||||||
|
this.secondAntecedent = secondAntecedent;
|
||||||
|
this.consequent = consequent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AntecedentValue getFirstAntecedentValue() {
|
||||||
|
return firstAntecedentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstAntecedentValue(AntecedentValue firstAntecedentValue) {
|
||||||
|
this.firstAntecedentValue = firstAntecedentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeriesType getFirstAntecedent() {
|
||||||
|
return firstAntecedent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstAntecedent(TimeSeriesType firstAntecedent) {
|
||||||
|
this.firstAntecedent = firstAntecedent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AntecedentValue getSecondAntecedentValue() {
|
||||||
|
return secondAntecedentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecondAntecedentValue(AntecedentValue secondAntecedentValue) {
|
||||||
|
this.secondAntecedentValue = secondAntecedentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeriesType getSecondAntecedent() {
|
||||||
|
return secondAntecedent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecondAntecedent(TimeSeriesType secondAntecedent) {
|
||||||
|
this.secondAntecedent = secondAntecedent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConsequent() {
|
||||||
|
return consequent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConsequent(String consequent) {
|
||||||
|
this.consequent = consequent;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package ru.ulstu.extractor.rule.repository;
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import ru.ulstu.extractor.rule.model.AntecedentValue;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface AntecedentValueRepository extends JpaRepository<AntecedentValue, Integer> {
|
||||||
|
Optional<AntecedentValue> findByAntecedentValue(String antecedentValue);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package ru.ulstu.extractor.rule.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import ru.ulstu.extractor.rule.model.DbRule;
|
||||||
|
|
||||||
|
public interface RuleRepository extends JpaRepository<DbRule, Integer> {
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package ru.ulstu.extractor.rule.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.rule.model.AntecedentValue;
|
||||||
|
import ru.ulstu.extractor.rule.repository.AntecedentValueRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AntecedentValueService {
|
||||||
|
private final AntecedentValueRepository antecedentValueRepository;
|
||||||
|
|
||||||
|
public AntecedentValueService(AntecedentValueRepository antecedentValueRepository) {
|
||||||
|
this.antecedentValueRepository = antecedentValueRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AntecedentValue> getList() {
|
||||||
|
return antecedentValueRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AntecedentValue getById(Integer antecedentValueId) {
|
||||||
|
return antecedentValueRepository.findById(antecedentValueId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Antecedent value not found by id " + antecedentValueId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AntecedentValue getByValue(String antecedentValue) {
|
||||||
|
return antecedentValueRepository.findByAntecedentValue(antecedentValue)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Antecedent value not found by value " + antecedentValue));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package ru.ulstu.extractor.rule.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.rule.model.AddRuleForm;
|
||||||
|
import ru.ulstu.extractor.rule.model.AntecedentValue;
|
||||||
|
import ru.ulstu.extractor.rule.model.DbRule;
|
||||||
|
import ru.ulstu.extractor.rule.repository.RuleRepository;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeriesType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class DbRuleService {
|
||||||
|
private final RuleRepository ruleRepository;
|
||||||
|
private final AntecedentValueService antecedentValueService;
|
||||||
|
|
||||||
|
public DbRuleService(RuleRepository ruleRepository,
|
||||||
|
AntecedentValueService antecedentValueService) {
|
||||||
|
this.ruleRepository = ruleRepository;
|
||||||
|
this.antecedentValueService = antecedentValueService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DbRule> getList() {
|
||||||
|
return ruleRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveRule(AddRuleForm addRuleForm) {
|
||||||
|
if (addRuleForm.getRuleId() != null) {
|
||||||
|
DbRule rule = ruleRepository.getOne(addRuleForm.getRuleId());
|
||||||
|
rule.setConsequent(addRuleForm.getConsequent());
|
||||||
|
rule.setFirstAntecedent(TimeSeriesType.valueOf(addRuleForm.getFirstAntecedentId()));
|
||||||
|
rule.setFirstAntecedentValue(antecedentValueService.getById(addRuleForm.getFirstAntecedentValueId()));
|
||||||
|
rule.setSecondAntecedent(TimeSeriesType.valueOf(addRuleForm.getSecondAntecedentId()));
|
||||||
|
rule.setSecondAntecedentValue(antecedentValueService.getById(addRuleForm.getSecondAntecedentValueId()));
|
||||||
|
ruleRepository.save(rule);
|
||||||
|
} else {
|
||||||
|
ruleRepository.save(new DbRule(antecedentValueService.getById(addRuleForm.getFirstAntecedentValueId()),
|
||||||
|
TimeSeriesType.valueOf(addRuleForm.getFirstAntecedentId()),
|
||||||
|
antecedentValueService.getById(addRuleForm.getSecondAntecedentValueId()),
|
||||||
|
TimeSeriesType.valueOf(addRuleForm.getSecondAntecedentId()),
|
||||||
|
addRuleForm.getConsequent()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveRule(TimeSeriesType timeSeriesType1, AntecedentValue antecedentValue1,
|
||||||
|
TimeSeriesType timeSeriesType2, AntecedentValue antecedentValue2,
|
||||||
|
String consequent) {
|
||||||
|
ruleRepository.save(new DbRule(antecedentValueService.getByValue(antecedentValue1.getAntecedentValue()),
|
||||||
|
timeSeriesType1,
|
||||||
|
antecedentValueService.getByValue(antecedentValue2.getAntecedentValue()),
|
||||||
|
timeSeriesType2,
|
||||||
|
consequent));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbRule findById(Integer id) {
|
||||||
|
return ruleRepository.getOne(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddRuleForm getAddRuleFormOrDefault(Integer id) {
|
||||||
|
return id != null
|
||||||
|
? new AddRuleForm(ruleRepository
|
||||||
|
.findById(id)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Правило не найдено")))
|
||||||
|
: new AddRuleForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteById(Integer id) {
|
||||||
|
ruleRepository.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getConsequentList() {
|
||||||
|
return ruleRepository.findAll().stream().map(DbRule::getConsequent).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,156 @@
|
|||||||
|
package ru.ulstu.extractor.rule.service;
|
||||||
|
|
||||||
|
import com.fuzzylite.Engine;
|
||||||
|
import com.fuzzylite.activation.General;
|
||||||
|
import com.fuzzylite.defuzzifier.Centroid;
|
||||||
|
import com.fuzzylite.norm.s.Maximum;
|
||||||
|
import com.fuzzylite.norm.t.AlgebraicProduct;
|
||||||
|
import com.fuzzylite.norm.t.Minimum;
|
||||||
|
import com.fuzzylite.rule.Rule;
|
||||||
|
import com.fuzzylite.rule.RuleBlock;
|
||||||
|
import com.fuzzylite.term.Activated;
|
||||||
|
import com.fuzzylite.term.Triangle;
|
||||||
|
import com.fuzzylite.variable.InputVariable;
|
||||||
|
import com.fuzzylite.variable.OutputVariable;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.extractor.assessment.model.Assessment;
|
||||||
|
import ru.ulstu.extractor.rule.model.AntecedentValue;
|
||||||
|
import ru.ulstu.extractor.rule.model.DbRule;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class FuzzyInferenceService {
|
||||||
|
private final static Logger LOG = LoggerFactory.getLogger(FuzzyInferenceService.class);
|
||||||
|
private final static String OUTPUT_VARIABLE_NAME = "state";
|
||||||
|
private final static String RULE_TEMPLATE = "if %s is %s and %s is %s then "
|
||||||
|
+ OUTPUT_VARIABLE_NAME
|
||||||
|
+ " is %s";
|
||||||
|
private final static String NO_RESULT = "Нет результата";
|
||||||
|
|
||||||
|
private List<String> mapRulesToString(List<DbRule> dbRules) {
|
||||||
|
return dbRules.stream().map(this::getFuzzyRule).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFuzzyRule(DbRule dbRule) {
|
||||||
|
return format(RULE_TEMPLATE,
|
||||||
|
dbRule.getFirstAntecedent().name(),
|
||||||
|
dbRule.getFirstAntecedentValue().getAntecedentValue(),
|
||||||
|
dbRule.getSecondAntecedent().name(),
|
||||||
|
dbRule.getSecondAntecedentValue().getAntecedentValue(),
|
||||||
|
dbRule.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private RuleBlock getRuleBlock(Engine engine,
|
||||||
|
List<DbRule> dbRules,
|
||||||
|
Map<String, Double> variableValues,
|
||||||
|
List<AntecedentValue> antecedentValues,
|
||||||
|
List<Integer> consequentValues) {
|
||||||
|
variableValues.forEach((key, value) -> {
|
||||||
|
InputVariable input = new InputVariable();
|
||||||
|
input.setName(key);
|
||||||
|
input.setDescription("");
|
||||||
|
input.setEnabled(true);
|
||||||
|
input.setRange(-1, 1);
|
||||||
|
input.setLockValueInRange(false);
|
||||||
|
input.addTerm(new Triangle("спад", -1, 0));
|
||||||
|
input.addTerm(new Triangle("стабильно", -0.1, 0.1));
|
||||||
|
input.addTerm(new Triangle("рост", 0, 1));
|
||||||
|
engine.addInputVariable(input);
|
||||||
|
});
|
||||||
|
|
||||||
|
OutputVariable output = new OutputVariable();
|
||||||
|
output.setName(OUTPUT_VARIABLE_NAME);
|
||||||
|
output.setDescription("");
|
||||||
|
output.setEnabled(true);
|
||||||
|
output.setRange(0, consequentValues.size() + 0.1);
|
||||||
|
output.setAggregation(new Maximum());
|
||||||
|
output.setDefuzzifier(new Centroid(10));
|
||||||
|
output.setDefaultValue(Double.NaN);
|
||||||
|
output.setLockValueInRange(false);
|
||||||
|
for (int i = 0; i < consequentValues.size(); i++) {
|
||||||
|
output.addTerm(new Triangle(consequentValues.get(i).toString(), i, i + 1));
|
||||||
|
}
|
||||||
|
engine.addOutputVariable(output);
|
||||||
|
|
||||||
|
RuleBlock mamdani = new RuleBlock();
|
||||||
|
mamdani.setName("mamdani");
|
||||||
|
mamdani.setDescription("");
|
||||||
|
mamdani.setEnabled(true);
|
||||||
|
mamdani.setConjunction(new Minimum());
|
||||||
|
//mamdani.setDisjunction(null);
|
||||||
|
mamdani.setImplication(new AlgebraicProduct());
|
||||||
|
mamdani.setActivation(new General());
|
||||||
|
mapRulesToString(dbRules).forEach(r -> {
|
||||||
|
LOG.info(r);
|
||||||
|
mamdani.addRule(Rule.parse(r, engine));
|
||||||
|
});
|
||||||
|
return mamdani;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Engine getFuzzyEngine() {
|
||||||
|
Engine engine = new Engine();
|
||||||
|
engine.setName("Git rules");
|
||||||
|
engine.setDescription("");
|
||||||
|
return engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Assessment> getFuzzyInference(List<DbRule> dbRules,
|
||||||
|
List<AntecedentValue> antecedentValues,
|
||||||
|
Map<String, Double> variableValues) {
|
||||||
|
validateVariables(variableValues, dbRules);
|
||||||
|
variableValues.entrySet().forEach(e -> System.out.println(e.getKey() + " " + e.getValue()));
|
||||||
|
Engine engine = getFuzzyEngine();
|
||||||
|
List<Integer> consequentValues = dbRules.stream().map(DbRule::getId).collect(Collectors.toList());
|
||||||
|
engine.addRuleBlock(getRuleBlock(engine, dbRules, variableValues, antecedentValues, consequentValues));
|
||||||
|
Map<String, Double> consequents = getConsequent(engine, variableValues);
|
||||||
|
if (consequents.containsKey(NO_RESULT)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<Assessment> assessments = new ArrayList<>();
|
||||||
|
for (Map.Entry<String, Double> consequent : consequents.entrySet()) {
|
||||||
|
for (DbRule dbRule : dbRules) {
|
||||||
|
if (dbRule.getId().equals(Integer.valueOf(consequent.getKey()))) {
|
||||||
|
assessments.add(new Assessment(dbRule, consequent.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return assessments;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void validateVariables(Map<String, Double> variableValues, List<DbRule> dbDbRules) {
|
||||||
|
for (DbRule dbRule : dbDbRules) {
|
||||||
|
if (!variableValues.containsKey(dbRule.getFirstAntecedent().name())) {
|
||||||
|
throw new RuntimeException(format("Переменной в правиле не задано значение (нет временного ряда): %s ",
|
||||||
|
dbRule.getFirstAntecedent().name()));
|
||||||
|
}
|
||||||
|
if (!variableValues.containsKey(dbRule.getSecondAntecedent().name())) {
|
||||||
|
throw new RuntimeException(format("Переменной в правиле не задано значение (нет временного ряда): %s ",
|
||||||
|
dbRule.getSecondAntecedent().name()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Double> getConsequent(Engine engine, Map<String, Double> variableValues) {
|
||||||
|
OutputVariable outputVariable = engine.getOutputVariable(OUTPUT_VARIABLE_NAME);
|
||||||
|
for (Map.Entry<String, Double> variableValue : variableValues.entrySet()) {
|
||||||
|
InputVariable inputVariable = engine.getInputVariable(variableValue.getKey());
|
||||||
|
inputVariable.setValue(variableValue.getValue());
|
||||||
|
}
|
||||||
|
engine.process();
|
||||||
|
if (outputVariable != null) {
|
||||||
|
LOG.info("Output: {}", outputVariable.getValue());
|
||||||
|
}
|
||||||
|
return Double.isNaN(outputVariable.getValue())
|
||||||
|
? Map.of(NO_RESULT, 0.0)
|
||||||
|
: outputVariable.fuzzyOutput().getTerms().stream().collect(Collectors.toMap(t -> t.getTerm().getName(), Activated::getDegree));
|
||||||
|
}
|
||||||
|
}
|
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.service;
|
|
||||||
|
|
||||||
import com.sun.istack.NotNull;
|
|
||||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import ru.ulstu.extractor.branch.model.Branch;
|
|
||||||
import ru.ulstu.extractor.branch.service.BranchService;
|
|
||||||
import ru.ulstu.extractor.gitrepository.GitRepositoryRepository;
|
|
||||||
import ru.ulstu.extractor.gitrepository.GitRepositoryService;
|
|
||||||
import ru.ulstu.extractor.gitrepository.model.GitRepository;
|
|
||||||
import ru.ulstu.extractor.model.Commit;
|
|
||||||
import ru.ulstu.extractor.ts.AbstractTimeSeriesCreator;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class IndexService {
|
|
||||||
private final static Logger LOG = LoggerFactory.getLogger(IndexService.class);
|
|
||||||
private final static int COMMITS_PAGE_SIZE = 10;
|
|
||||||
private final GitRepositoryService gitRepositoryService;
|
|
||||||
private final GitRepositoryRepository gitRepositoryRepository;
|
|
||||||
private final BranchService branchService;
|
|
||||||
private final List<AbstractTimeSeriesCreator> timeSeriesCreators;
|
|
||||||
|
|
||||||
public IndexService(GitRepositoryService gitRepositoryService,
|
|
||||||
GitRepositoryRepository gitRepositoryRepository,
|
|
||||||
BranchService branchService,
|
|
||||||
List<AbstractTimeSeriesCreator> timeSeriesCreators) {
|
|
||||||
this.gitRepositoryService = gitRepositoryService;
|
|
||||||
this.gitRepositoryRepository = gitRepositoryRepository;
|
|
||||||
this.branchService = branchService;
|
|
||||||
this.timeSeriesCreators = timeSeriesCreators;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void index(@NotNull String repositoryUrl, @NotNull String branchName) throws GitAPIException, IOException {
|
|
||||||
GitRepository gitRepository = gitRepositoryRepository.findByUrl(repositoryUrl);
|
|
||||||
if (gitRepository == null) {
|
|
||||||
gitRepository = gitRepositoryRepository.save(new GitRepository(repositoryUrl));
|
|
||||||
}
|
|
||||||
Branch branch = branchService.findByRepositoryAndName(gitRepository, branchName);
|
|
||||||
if (branch == null) {
|
|
||||||
branch = new Branch(gitRepository, branchName);
|
|
||||||
}
|
|
||||||
branchService.save(branch, Collections.emptyList());
|
|
||||||
int commitsFrom = 0;
|
|
||||||
int commitsTo = COMMITS_PAGE_SIZE;
|
|
||||||
List<Commit> commits = gitRepositoryService.getCommits(repositoryUrl, branchName, commitsFrom, commitsTo, true);
|
|
||||||
while (!commits.isEmpty()) {
|
|
||||||
LOG.debug("{} commits loaded.", commits.size());
|
|
||||||
branchService.addCommits(branch, commits);
|
|
||||||
LOG.debug("{} commits successfully saved. {} {}", commits.size(), repositoryUrl, branchName);
|
|
||||||
commitsFrom += COMMITS_PAGE_SIZE;
|
|
||||||
commitsTo += COMMITS_PAGE_SIZE;
|
|
||||||
commits = gitRepositoryService.getCommits(repositoryUrl, branchName, commitsFrom, commitsTo, false);
|
|
||||||
}
|
|
||||||
Integer repositoryId = gitRepository.getId();
|
|
||||||
timeSeriesCreators.forEach(tsCreator -> tsCreator.addTimeSeries(repositoryId, branchName));
|
|
||||||
LOG.debug("Complete indexing {} branch", branchName);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.service;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import ru.ulstu.extractor.http.HttpService;
|
|
||||||
import ru.ulstu.extractor.http.JsonTimeSeries;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeries;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.repository.TimeSeriesRepository;
|
|
||||||
import ru.ulstu.extractor.repository.TimeSeriesValueRepository;
|
|
||||||
import ru.ulstu.extractor.ts.TimeSeriesDateMapper;
|
|
||||||
|
|
||||||
import javax.transaction.Transactional;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class TimeSeriesService {
|
|
||||||
private final static Logger LOG = LoggerFactory.getLogger(TimeSeriesService.class);
|
|
||||||
private final TimeSeriesRepository timeSeriesRepository;
|
|
||||||
private final TimeSeriesValueRepository timeSeriesValueRepository;
|
|
||||||
private final TimeSeriesDateMapper.TimeSeriesInterval timeSeriesInterval = TimeSeriesDateMapper.TimeSeriesInterval.HOUR;
|
|
||||||
private final HttpService httpService;
|
|
||||||
private final static String TIME_SERIES_SERVICE_URL = "http://time-series.athene.tech/api/1.0/add-time-series?setKey=git-extractor";
|
|
||||||
|
|
||||||
public TimeSeriesService(TimeSeriesRepository timeSeriesRepository,
|
|
||||||
TimeSeriesValueRepository timeSeriesValueRepository,
|
|
||||||
HttpService httpService) {
|
|
||||||
this.timeSeriesRepository = timeSeriesRepository;
|
|
||||||
this.timeSeriesValueRepository = timeSeriesValueRepository;
|
|
||||||
this.httpService = httpService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Сохранить список временных рядов
|
|
||||||
*
|
|
||||||
* @param timeSeriesValues
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Transactional
|
|
||||||
public List<TimeSeries> save(Map<String, List<TimeSeriesValue>> timeSeriesValues) {
|
|
||||||
List<TimeSeries> results = new ArrayList<>();
|
|
||||||
for (Map.Entry<String, List<TimeSeriesValue>> entry : timeSeriesValues.entrySet()) {
|
|
||||||
results.add(save(entry.getKey(), entry.getValue()));
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public TimeSeries save(String timeSeriesName, List<TimeSeriesValue> timeSeriesValues) {
|
|
||||||
LOG.debug("Start save {} time series with {} time series values ", timeSeriesName, timeSeriesValues.size());
|
|
||||||
final TimeSeries timeSeries = findOrCreate(timeSeriesName);
|
|
||||||
List<TimeSeriesValue> timeSeriesValuesToRemove = timeSeries.getValues();
|
|
||||||
timeSeries.setValues(timeSeriesValues);
|
|
||||||
LOG.debug("Save time series {} ", timeSeries.getName());
|
|
||||||
TimeSeries savedTimeSeries = timeSeriesRepository.save(timeSeries);
|
|
||||||
LOG.debug("Clear {} time series values ", timeSeriesValuesToRemove.size());
|
|
||||||
timeSeriesValueRepository.deleteAll(timeSeriesValuesToRemove);
|
|
||||||
sendToTimeSeriesService(savedTimeSeries);
|
|
||||||
return savedTimeSeries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeSeries findOrCreate(String timeSeriesName) {
|
|
||||||
Optional<TimeSeries> maybeTimeSeries = timeSeriesRepository.findByName(timeSeriesName);
|
|
||||||
if (maybeTimeSeries.isPresent()) {
|
|
||||||
LOG.debug("TimeSeries {} exists.", maybeTimeSeries.get().getName());
|
|
||||||
return maybeTimeSeries.get();
|
|
||||||
}
|
|
||||||
return timeSeriesRepository.save(new TimeSeries(timeSeriesName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TimeSeriesValue> save(List<TimeSeriesValue> timeSeriesValues) {
|
|
||||||
return timeSeriesValues.stream()
|
|
||||||
.map(timeSeriesValue -> {
|
|
||||||
timeSeriesValue.setValue((timeSeriesValue.getValue()));
|
|
||||||
timeSeriesValue.setDate((timeSeriesValue.getDate()));
|
|
||||||
return timeSeriesValueRepository.save(timeSeriesValue);
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTimeSeriesValue(String timeSeriesName, Date date, Double value) {
|
|
||||||
LOG.debug("Start add time series values to {} time series values ", timeSeriesName);
|
|
||||||
TimeSeries timeSeries = findOrCreate(timeSeriesName);
|
|
||||||
timeSeriesValueRepository.save(new TimeSeriesValue(timeSeries, date, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TimeSeriesValue> findAll() {
|
|
||||||
return timeSeriesValueRepository.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeSeriesDateMapper.TimeSeriesInterval getTimeSeriesInterval() {
|
|
||||||
return timeSeriesInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendToTimeSeriesService(TimeSeries timeSeries) {
|
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
httpService.post(TIME_SERIES_SERVICE_URL, new JSONObject(new JsonTimeSeries(timeSeries)));
|
|
||||||
LOG.debug("Успешно отправлен на сервис");
|
|
||||||
} catch (Exception ex) {
|
|
||||||
LOG.debug(ex.getMessage());
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static ru.ulstu.extractor.ts.TimeSeriesDateMapper.mapTimeSeriesToInterval;
|
|
||||||
|
|
||||||
public abstract class AbstractTimeSeriesCreator {
|
|
||||||
|
|
||||||
public abstract String getTimeSeriesName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Извлечь список точек временных рядов
|
|
||||||
*
|
|
||||||
* @param repositoryId
|
|
||||||
* @param branchName
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public abstract Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName);
|
|
||||||
|
|
||||||
public abstract TimeSeriesService getTimeSeriesService();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Сохранить извлеченные временные ряды
|
|
||||||
*
|
|
||||||
* @param repositoryId
|
|
||||||
* @param branchName
|
|
||||||
*/
|
|
||||||
public void addTimeSeries(Integer repositoryId, String branchName) {
|
|
||||||
// извлеченные точки временных рядов
|
|
||||||
Map<String, List<TimeSeriesValue>> timeSeriesValues = getTimeSeriesValues(repositoryId, branchName);
|
|
||||||
|
|
||||||
// сгруппированные по временным интервалам точки временных рядов
|
|
||||||
timeSeriesValues.replaceAll((k, v) -> mapTimeSeriesToInterval(getTimeSeriesService().getTimeSeriesInterval(), v));
|
|
||||||
getTimeSeriesService().save(timeSeriesValues);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class AuthorTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public AuthorTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество Авторов";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class AuthorsCommentTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public AuthorsCommentTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество коммитов авторов";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class AuthorsCompletedIssueTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public AuthorsCompletedIssueTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество выполненных issues авторов";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class AuthorsIssueTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public AuthorsIssueTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество issues авторов";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class BranchTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public BranchTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество веток";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class ClassTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public ClassTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество классов";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.commit.service.CommitService;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class CommitsTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
private final CommitService commitService;
|
|
||||||
|
|
||||||
public CommitsTS(TimeSeriesService timeSeriesService,
|
|
||||||
CommitService commitService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
this.commitService = commitService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество коммитов во времени";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
//TODO: добавить постраничное чтение
|
|
||||||
Map<String, List<TimeSeriesValue>> result = new HashMap<>();
|
|
||||||
result.put(String.format("%s %s %s", getTimeSeriesName(), repositoryId, branchName),
|
|
||||||
commitService.findByRepositoryIdAndName(repositoryId, branchName)
|
|
||||||
.stream()
|
|
||||||
.map(c -> new TimeSeriesValue(c.getDate(), 1.0))
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class DependenceTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public DependenceTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество зависимостей";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class EntityTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public EntityTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество сущностей";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class FileTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public FileTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество файлов";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class InterfaceTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public InterfaceTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество интерфейсов";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class IssuesTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public IssuesTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество issues созданных во времени";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class ProcessTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public ProcessTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество процессов";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ru.ulstu.extractor.ts;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.ulstu.extractor.model.TimeSeriesValue;
|
|
||||||
import ru.ulstu.extractor.service.TimeSeriesService;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class StarTS extends AbstractTimeSeriesCreator {
|
|
||||||
private final TimeSeriesService timeSeriesService;
|
|
||||||
|
|
||||||
public StarTS(TimeSeriesService timeSeriesService) {
|
|
||||||
this.timeSeriesService = timeSeriesService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTimeSeriesName() {
|
|
||||||
return "Количество звезд";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<TimeSeriesValue>> getTimeSeriesValues(Integer repositoryId, String branchName) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesService getTimeSeriesService() {
|
|
||||||
return timeSeriesService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,10 @@
|
|||||||
|
package ru.ulstu.extractor.ts.creator;
|
||||||
|
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeriesType;
|
||||||
|
import ru.ulstu.extractor.ts.service.TimeSeriesService;
|
||||||
|
|
||||||
|
public abstract class AbstractTimeSeriesCreator {
|
||||||
|
public abstract TimeSeriesType getTimeSeriesType();
|
||||||
|
|
||||||
|
public abstract TimeSeriesService getTimeSeriesService();
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package ru.ulstu.extractor.ts.creator.db;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import ru.ulstu.extractor.author.model.Author;
|
||||||
|
import ru.ulstu.extractor.author.service.AuthorService;
|
||||||
|
import ru.ulstu.extractor.branch.model.Branch;
|
||||||
|
import ru.ulstu.extractor.branch.service.BranchService;
|
||||||
|
import ru.ulstu.extractor.commit.model.Commit;
|
||||||
|
import ru.ulstu.extractor.commit.service.CommitService;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeries;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeriesType;
|
||||||
|
import ru.ulstu.extractor.ts.model.TimeSeriesValue;
|
||||||
|
import ru.ulstu.extractor.ts.service.TimeSeriesService;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AuthorsCommitTS extends DBTimeSeriesCreator {
|
||||||
|
private final TimeSeriesService timeSeriesService;
|
||||||
|
private final CommitService commitService;
|
||||||
|
private final AuthorService authorService;
|
||||||
|
private final BranchService branchService;
|
||||||
|
|
||||||
|
public AuthorsCommitTS(TimeSeriesService timeSeriesService,
|
||||||
|
CommitService commitService,
|
||||||
|
AuthorService authorService,
|
||||||
|
BranchService branchService) {
|
||||||
|
this.timeSeriesService = timeSeriesService;
|
||||||
|
this.commitService = commitService;
|
||||||
|
this.authorService = authorService;
|
||||||
|
this.branchService = branchService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeSeriesType getTimeSeriesType() {
|
||||||
|
return TimeSeriesType.AUTHOR_COMMITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TimeSeries> getTimeSeries(Branch branch) {
|
||||||
|
List<TimeSeries> timeSeriesResult = new ArrayList<>();
|
||||||
|
List<Author> authors = authorService.findAll();
|
||||||
|
List<Commit> commits = new ArrayList<>(commitService.findByRepositoryIdAndName(branch.getGitRepository().getId(),
|
||||||
|
branch.getName()));
|
||||||
|
for (Author author : authors) {
|
||||||
|
TimeSeries timeSeries = new TimeSeries(
|
||||||
|
String.format("%s %s %s %s",
|
||||||
|
branch.getGitRepository().getName(),
|
||||||
|
branch.getName(),
|
||||||
|
author.getName(),
|
||||||
|
getTimeSeriesType().getDescription()),
|
||||||
|
branchService.findByRepositoryAndName(branch.getGitRepository(),
|
||||||
|
branch.getName()),
|
||||||
|
getTimeSeriesType());
|
||||||
|
for (Commit commit : commits) {
|
||||||
|
if (commit.getAuthor().equals(author)) {
|
||||||
|
timeSeries.getValues().add(new TimeSeriesValue(commit.getDate(), 1.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!timeSeries.getValues().isEmpty()) {
|
||||||
|
timeSeriesResult.add(timeSeries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return timeSeriesResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeSeriesService getTimeSeriesService() {
|
||||||
|
return timeSeriesService;
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user