diff --git a/src/main/java/ru/ulstu/extractor/branch/model/Branch.java b/src/main/java/ru/ulstu/extractor/branch/model/Branch.java index 6d63841..7c428d0 100644 --- a/src/main/java/ru/ulstu/extractor/branch/model/Branch.java +++ b/src/main/java/ru/ulstu/extractor/branch/model/Branch.java @@ -6,14 +6,7 @@ import ru.ulstu.extractor.commit.model.Commit; import ru.ulstu.extractor.core.BaseEntity; import ru.ulstu.extractor.gitrepository.model.GitRepository; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; +import javax.persistence.*; import java.util.ArrayList; import java.util.List; @@ -21,6 +14,7 @@ import static ru.ulstu.extractor.branch.model.IndexingStatus.EMPTY; @Entity public class Branch extends BaseEntity { + public static Integer GENERATED_BRANCH_ID = 1; private String name; @ManyToOne diff --git a/src/main/java/ru/ulstu/extractor/core/Route.java b/src/main/java/ru/ulstu/extractor/core/Route.java index 9c56182..0b2fe3f 100644 --- a/src/main/java/ru/ulstu/extractor/core/Route.java +++ b/src/main/java/ru/ulstu/extractor/core/Route.java @@ -18,6 +18,8 @@ public class Route { 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() { return LIST_INDEXED_REPOSITORIES; } @@ -45,4 +47,8 @@ public class Route { public static String getADD_MARKUP() { return ADD_MARKUP; } + + public static String getGENERATION() { + return GENERATION; + } } diff --git a/src/main/java/ru/ulstu/extractor/generation/controller/GenerationController.java b/src/main/java/ru/ulstu/extractor/generation/controller/GenerationController.java new file mode 100644 index 0000000..fcb9dc4 --- /dev/null +++ b/src/main/java/ru/ulstu/extractor/generation/controller/GenerationController.java @@ -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; + } +} diff --git a/src/main/java/ru/ulstu/extractor/generation/model/GenerationForm.java b/src/main/java/ru/ulstu/extractor/generation/model/GenerationForm.java new file mode 100644 index 0000000..e1e2c69 --- /dev/null +++ b/src/main/java/ru/ulstu/extractor/generation/model/GenerationForm.java @@ -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; + } +} diff --git a/src/main/java/ru/ulstu/extractor/generation/service/GenerationService.java b/src/main/java/ru/ulstu/extractor/generation/service/GenerationService.java new file mode 100644 index 0000000..34a160d --- /dev/null +++ b/src/main/java/ru/ulstu/extractor/generation/service/GenerationService.java @@ -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 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 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; + } +} diff --git a/src/main/java/ru/ulstu/extractor/gitrepository/controler/RepositoryController.java b/src/main/java/ru/ulstu/extractor/gitrepository/controler/RepositoryController.java index d27ee14..cefbe4d 100644 --- a/src/main/java/ru/ulstu/extractor/gitrepository/controler/RepositoryController.java +++ b/src/main/java/ru/ulstu/extractor/gitrepository/controler/RepositoryController.java @@ -7,8 +7,11 @@ import org.springframework.web.bind.annotation.RequestParam; import ru.ulstu.extractor.gitrepository.repository.GitRepositoryRepository; import springfox.documentation.annotations.ApiIgnore; +import java.util.stream.Collectors; + 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 @ApiIgnore @@ -21,7 +24,10 @@ public class RepositoryController { @GetMapping(LIST_INDEXED_REPOSITORIES) 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; } @@ -29,7 +35,10 @@ public class RepositoryController { public String deleteRepo(Model model, @RequestParam Integer 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; } } diff --git a/src/main/java/ru/ulstu/extractor/gitrepository/controler/StatisticController.java b/src/main/java/ru/ulstu/extractor/gitrepository/controler/StatisticController.java index 63e75d8..766d3a7 100644 --- a/src/main/java/ru/ulstu/extractor/gitrepository/controler/StatisticController.java +++ b/src/main/java/ru/ulstu/extractor/gitrepository/controler/StatisticController.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +import static ru.ulstu.extractor.branch.model.Branch.GENERATED_BRANCH_ID; import static ru.ulstu.extractor.core.Route.STATISTIC; @Controller @@ -60,7 +61,9 @@ public class StatisticController { filterForm.setEntity(entity.orElse(null)); model.addAttribute("filterForm", filterForm); 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))); return STATISTIC; } diff --git a/src/main/java/ru/ulstu/extractor/gitrepository/model/GitRepository.java b/src/main/java/ru/ulstu/extractor/gitrepository/model/GitRepository.java index f4707c7..8017241 100644 --- a/src/main/java/ru/ulstu/extractor/gitrepository/model/GitRepository.java +++ b/src/main/java/ru/ulstu/extractor/gitrepository/model/GitRepository.java @@ -7,6 +7,8 @@ import javax.persistence.Entity; @Entity public class GitRepository extends BaseEntity { + + public static Integer GENERATED_REPOSITORY_ID = 1; private String url; private String repositoryId; diff --git a/src/main/java/ru/ulstu/extractor/markup/controller/TimeSeriesMarkupController.java b/src/main/java/ru/ulstu/extractor/markup/controller/TimeSeriesMarkupController.java index 3aef93a..ad67a0d 100644 --- a/src/main/java/ru/ulstu/extractor/markup/controller/TimeSeriesMarkupController.java +++ b/src/main/java/ru/ulstu/extractor/markup/controller/TimeSeriesMarkupController.java @@ -14,6 +14,9 @@ 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 @@ -32,14 +35,18 @@ public class TimeSeriesMarkupController { @GetMapping("time-series-markup") public String markupTs(Model model) { - model.addAttribute("branches", branchService.findAllValid()); + 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()); + model.addAttribute("branches", branchService.findAllValid().stream() + .filter(r -> !r.getId().equals(GENERATED_BRANCH_ID)) + .collect(Collectors.toList())); if (markupForm != null && markupForm.getBranchId() != null) { List tss = markupService.getTimeSeriesForMarkup( timeSeriesService.getGroupedTendencies( @@ -56,7 +63,9 @@ public class TimeSeriesMarkupController { @PostMapping(Route.ADD_MARKUP) public String addMarkups(Model model, @ModelAttribute MarkupForm markupForm) { - model.addAttribute("branches", branchService.findAllValid()); + model.addAttribute("branches", branchService.findAllValid().stream() + .filter(r -> !r.getId().equals(GENERATED_BRANCH_ID)) + .collect(Collectors.toList())); if (markupForm != null && markupForm.getBranchId() != null) { List tss = markupService.getTimeSeriesForMarkup( timeSeriesService.getGroupedTendencies( diff --git a/src/main/java/ru/ulstu/extractor/ts/service/ScheduledTimeSeriesService.java b/src/main/java/ru/ulstu/extractor/ts/service/ScheduledTimeSeriesService.java index d3fe476..5b961f9 100644 --- a/src/main/java/ru/ulstu/extractor/ts/service/ScheduledTimeSeriesService.java +++ b/src/main/java/ru/ulstu/extractor/ts/service/ScheduledTimeSeriesService.java @@ -9,6 +9,9 @@ import ru.ulstu.extractor.branch.service.BranchService; import ru.ulstu.extractor.ts.creator.scheduled.ScheduledTimeSeriesCreator; import java.util.List; +import java.util.stream.Collectors; + +import static ru.ulstu.extractor.branch.model.Branch.GENERATED_BRANCH_ID; @Service public class ScheduledTimeSeriesService { @@ -25,7 +28,10 @@ public class ScheduledTimeSeriesService { @Scheduled(cron = "0 0 8 * * *") public void addTimeSeriesPoints() { log.info("Старт добавления новых точек временного ряда"); - List branches = branchService.findAll(); + List branches = branchService.findAll() + .stream() + .filter(b -> !b.getId().equals(GENERATED_BRANCH_ID)) + .collect(Collectors.toList()); branches.forEach(branch -> { scheduledTimeSeriesCreators.forEach(creator -> creator.addTimeSeriesValue(branch)); }); diff --git a/src/main/java/ru/ulstu/extractor/ts/util/DateUtils.java b/src/main/java/ru/ulstu/extractor/ts/util/DateUtils.java index 773e9e0..d998853 100644 --- a/src/main/java/ru/ulstu/extractor/ts/util/DateUtils.java +++ b/src/main/java/ru/ulstu/extractor/ts/util/DateUtils.java @@ -5,9 +5,16 @@ import java.util.Date; import java.util.GregorianCalendar; public class DateUtils { - public static Date addMonths(int amount) { + public static Date addDays(int amount) { Calendar c = GregorianCalendar.getInstance(); c.add(Calendar.DAY_OF_MONTH, amount); return c.getTime(); } + + public static Date addDays(Date startDate, int amount) { + Calendar c = GregorianCalendar.getInstance(); + c.setTime(startDate); + c.add(Calendar.DAY_OF_MONTH, amount); + return c.getTime(); + } } diff --git a/src/main/java/ru/ulstu/extractor/ts/util/Dummy.java b/src/main/java/ru/ulstu/extractor/ts/util/Dummy.java index 61b0389..59fcd52 100644 --- a/src/main/java/ru/ulstu/extractor/ts/util/Dummy.java +++ b/src/main/java/ru/ulstu/extractor/ts/util/Dummy.java @@ -6,10 +6,10 @@ import java.util.List; public class Dummy { public static List getDefaultTimeSeries (){ - return List.of(new TimeSeriesValue(DateUtils.addMonths(-5), 1.0), - new TimeSeriesValue(DateUtils.addMonths(-4), 2.0), - new TimeSeriesValue(DateUtils.addMonths(-3), 3.0), - new TimeSeriesValue(DateUtils.addMonths(-2), 4.0), - new TimeSeriesValue(DateUtils.addMonths(-1), 5.0)); + return List.of(new TimeSeriesValue(DateUtils.addDays(-5), 1.0), + new TimeSeriesValue(DateUtils.addDays(-4), 2.0), + new TimeSeriesValue(DateUtils.addDays(-3), 3.0), + new TimeSeriesValue(DateUtils.addDays(-2), 4.0), + new TimeSeriesValue(DateUtils.addDays(-1), 5.0)); } } diff --git a/src/main/resources/db/changelog-20230302_210000-schema.xml b/src/main/resources/db/changelog-20230302_210000-schema.xml index 670658e..135ac55 100644 --- a/src/main/resources/db/changelog-20230302_210000-schema.xml +++ b/src/main/resources/db/changelog-20230302_210000-schema.xml @@ -46,4 +46,15 @@ + + + 1 + Генерированный репозиторий + + + 1 + Сгенерированные показатели + 1 + + \ No newline at end of file diff --git a/src/main/resources/templates/assessments.html b/src/main/resources/templates/assessments.html index d9a3721..aae7805 100644 --- a/src/main/resources/templates/assessments.html +++ b/src/main/resources/templates/assessments.html @@ -3,7 +3,7 @@ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml" layout:decorate="~{default}"> - Простая обработка формы на Spring MVC + Оценка репозиториев
diff --git a/src/main/resources/templates/default.html b/src/main/resources/templates/default.html index aa66144..7303d7e 100644 --- a/src/main/resources/templates/default.html +++ b/src/main/resources/templates/default.html @@ -38,6 +38,9 @@ + diff --git a/src/main/resources/templates/generation.html b/src/main/resources/templates/generation.html new file mode 100644 index 0000000..ef7fd1d --- /dev/null +++ b/src/main/resources/templates/generation.html @@ -0,0 +1,74 @@ + + + + Генерация + + +
+
+
+
+ Длина временных рядов +
+
+ +
+
+
+
+ Минимум +
+
+ +
+
+
+
+ Максимум +
+
+ +
+
+
+
+ Основное значение +
+
+ +
+
+
+
+ Основная тенденция +
+
+ +
+
+
+
+ Динамика тенденции +
+
+ +
+
+
+
+ Величина шума +
+
+ +
+
+
+
+ +
+
+
+
+