Compare commits

..

4 Commits
dev ... 48-crud

Author SHA1 Message Date
AlexGames73
2728a0ca01 Add: register page, account info page 2019-01-11 23:08:13 +04:00
AlexGames73
cf0e05c918 Fix gradle v2 2019-01-10 21:51:11 +04:00
AlexGames73
bd7e12220b Fix gradle 2019-01-10 21:46:54 +04:00
AlexGames73
383bbc343f Add ReactJS to project 2019-01-10 17:50:23 +04:00
311 changed files with 3451 additions and 14242 deletions

View File

@ -1,35 +1,40 @@
image: romanov73/is:ng-tracker-container-11 image: ubuntu:18.04
cache:
key: "$CI_PROJECT_ID"
paths:
- .gradle/
variables: variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false" GRADLE_OPTS: "-Dorg.gradle.daemon=false"
before_script: before_script:
- service postgresql stop - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- service postgresql start - apt-get install openjdk-8-jdk git -y
- eval $(ssh-agent -s) - eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh - mkdir -p ~/.ssh
- chmod 700 ~/.ssh - chmod 700 ~/.ssh
- git log --pretty="%cn;%cd;%s" > src/main/resources/commits.log
build: build:
stage: build stage: build
script: ./gradlew assemble script: ./gradlew assemble
cache:
checkRun: key: "$CI_PROJECT_ID"
stage: test policy: push
script: ./gradlew bootRun -Dng-tracker.check-run=true paths:
- build
checkStyle: - .gradle
stage: test
script: ./gradlew check -x test
deploy: deploy:
stage: deploy stage: deploy
script: script:
- sh deploy/gdccloud/deploy.sh - sh deploy/gdccloud/deploy.sh
only: only:
- dev - master
environment: cache:
name: staging key: "$CI_PROJECT_ID"
url: http://193.110.3.124:8080 policy: pull
paths:
- build
- .gradle

View File

@ -1,46 +0,0 @@
## Краткое описание задачи
Что требуется сделать
## `Опционально` Список верстаемых страниц
Будут затронуты страницы:
* page1.html
* page2.html
* page3.html
## `Опционально` Список затрагиваемых модулей
При реализации задачи потребуется также реализовать методы контроллера
## `Опционально` Список реализуемых функций
После выполнения задачи станет доступным:
* просмотр `entity_name`
* редактирование `entity_name`
* валидация `entity_name`
## `Опционально` Сценарии работы
Сценарий просмотра:
1. Зайти на главную страницу приложения
2. Перейти в раздел `section_name`
3. Перейти к списку `entity_name`
4. Выбрать нужную `entity_name` и нажать на нее
Сценарий редактирования:
1. Зайти на главную страницу приложения
2. Перейти в раздел `section_name`
3. Перейти к списку `entity_name`
4. Выбрать нужную `entity_name` и нажать на нее
5. Внести нужные правки в поля и сохранить
## Описание конечного результата, дающего возможность проверки выполнения задачи: компоненты проекта, сценарии работы
* Сверстаны страницы page1.hml, page2.hml, page3.hml
* Реализован контроллер для обслуживания страниц
* Сохранение в БД еще не реализовано
* Валидация происходит по полям `field1, field2`
* Сценарий просмотра проверяется при ручном внечении записей в БД

19
Jenkinsfile vendored
View File

@ -1,19 +0,0 @@
pipeline {
agent any
stages {
stage('Test') {
steps {
sh "./gradlew clean test --info"
}
}
}
post {
always {
script {
if (currentBuild.currentResult == 'FAILURE') {
step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: "a.romanov@ulstu.ru", sendToIndividuals: true])
}
}
}
}
}

View File

@ -7,6 +7,7 @@
2. Создать новую функцию автоматизированной системы управления задчами - интеллектуальную постановку задач исполнителям. 2. Создать новую функцию автоматизированной системы управления задчами - интеллектуальную постановку задач исполнителям.
3. Получить платформу для обкатки научных проектов магистрантов по созданию интеллектуальны систем. 3. Получить платформу для обкатки научных проектов магистрантов по созданию интеллектуальны систем.
4. Получить проект для обучения бакалавров современым технологиям разработки. 4. Получить проект для обучения бакалавров современым технологиям разработки.
5. Создать систему хранения и трансляции опыта между участниками научной группы.
[Для разворачивания проекта и ведения разработки ознакомьтесь с wiki](https://git.athene.tech/romanov73/ng-tracker/wiki/home) [Демо версия доступна здесь](https://193.110.3.124:8080)
[Для разворачивания проекта и ведения разработки ознакомьтесь с wiki](https://gitlab.com/romanov73/ng-tracker/wikis/home)

View File

@ -1,23 +1,34 @@
plugins { buildscript {
id 'java' ext {
id 'org.springframework.boot' version '3.2.4' versionSpringBoot = '1.5.10.RELEASE'
id 'io.spring.dependency-management' version '1.1.4' }
id 'checkstyle'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath group: 'org.springframework.boot', name: 'spring-boot-gradle-plugin', version: versionSpringBoot
}
} }
group 'ru.ulstu' group 'ru.ulstu'
version '0.1.0-SNAPSHOT' version '0.1.0-SNAPSHOT'
apply plugin: 'application'
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'checkstyle'
mainClassName = 'ru.ulstu.NgTrackerApplication'
build.dependsOn checkstyleMain build.dependsOn checkstyleMain
bootRun.dependsOn checkstyleMain bootRun.dependsOn checkstyleMain
java { sourceCompatibility = 1.8
sourceCompatibility = '17' targetCompatibility = 1.8
}
bootRun {
systemProperties = System.properties
}
checkstyle { checkstyle {
@ -61,16 +72,9 @@ task health(dependsOn: [
'checkstyleMain' 'checkstyleMain'
]) ])
test {
useJUnitPlatform()
}
jar { jar {
enabled = false baseName = 'ng-tracker'
}
bootJar {
archiveFileName = String.format('%s-%s.jar', rootProject.name, version)
} }
compileJava { compileJava {
@ -82,39 +86,49 @@ repositories {
mavenCentral() mavenCentral()
} }
configurations {
compile.exclude module: "spring-boot-starter-tomcat"
compile.exclude module: "bcmail-jdk14"
compile.exclude module: "bcprov-jdk14"
compile.exclude module: "bctsp-jdk14"
}
dependencies { dependencies {
implementation('org.springframework.boot:spring-boot-starter-web') { compile group: 'org.springframework.boot', name: 'spring-boot-starter-web'
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' compile group: 'org.springframework.boot', name: 'spring-boot-starter-security'
} compile group: 'org.springframework.boot', name: 'spring-boot-starter-aop'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security' compile group: 'org.springframework.boot', name: 'spring-boot-starter-mail'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-aop' compile group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-mail' compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jetty' compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa' compile group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-springsecurity4'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf' compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-afterburner'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation' compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate5'
implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect'
implementation group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-springsecurity6' compile group: 'postgresql', name: 'postgresql', version: '9.1-901.jdbc4'
implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-afterburner'
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate5' compile group: 'org.liquibase', name: 'liquibase-core', version: '3.5.3'
compile group: 'com.mattbertolini', name: 'liquibase-slf4j', version: '2.0.0'
implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.5'
compile group: 'org.apache.poi', name: 'poi', version: '3.9'
implementation group: 'org.liquibase', name: 'liquibase-core', version: '4.27.0' compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.9'
implementation group: 'com.mattbertolini', name: 'liquibase-slf4j', version: '2.0.0'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.7'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.7'
compile group: 'org.webjars', name: 'bootstrap', version: '4.1.0'
implementation group: 'org.webjars', name: 'bootstrap', version: '5.3.3' compile group: 'org.webjars', name: 'bootstrap-select', version: '1.13.3'
runtimeOnly group: 'org.webjars', name: 'bootstrap-select', version: '1.4.2' compile group: 'org.webjars', name: 'jquery', version: '3.3.1-1'
implementation group: 'org.webjars', name: 'jquery', version: '3.7.1' compile group: 'org.webjars.npm', name: 'jquery.easing', version: '1.4.1'
implementation group: 'org.webjars', name: 'jquery-easing', version: '1.4.1' compile group: 'org.webjars', name: 'font-awesome', version: '4.7.0'
implementation group: 'org.webjars', name: 'font-awesome', version: '4.7.0' compile group: 'org.webjars.npm', name: 'react', version: '16.7.0'
compile group: 'org.webjars.npm', name: 'react-dom', version: '16.7.0'
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.8.0' compile group: 'org.webjars.npm', name: 'material-ui__core', version: '3.5.1'
implementation group: 'net.sourceforge.htmlunit', name: 'htmlunit', version: '2.35.0' compile group: 'org.webjars.npm', name: 'babel-standalone', version: '6.26.0'
implementation group: 'xalan', name: 'xalan', version: '2.7.2' compile group: 'org.webjars.npm', name: 'babel__runtime', version: '7.2.0'
compile group: 'org.webjars.npm', name: 'js-tokens', version: '4.0.0'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-test'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.2' compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.5.0'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.5.0'
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test'
} }

View File

@ -100,7 +100,7 @@
<!-- Checks for imports --> <!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html --> <!-- See http://checkstyle.sf.net/config_import.html -->
<module name="AvoidStarImport"/> <!--<module name="AvoidStarImport"/>-->
<module name="IllegalImport"/> <!-- defaults to sun.* packages --> <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/> <module name="RedundantImport"/>
<!--module name="UnusedImports"> <!--module name="UnusedImports">
@ -136,7 +136,7 @@
<module name="AvoidNestedBlocks"/> <module name="AvoidNestedBlocks"/>
<module name="EmptyBlock"/> <module name="EmptyBlock"/>
<module name="LeftCurly"/> <module name="LeftCurly"/>
<module name="NeedBraces"/> <!--<module name="NeedBraces"/>-->
<module name="RightCurly"/> <module name="RightCurly"/>
<!-- Checks for common coding problems --> <!-- Checks for common coding problems -->

View File

@ -18,6 +18,6 @@ fi
ssh $USERSERVER "cd /tmp && rm -rf $ARTIFACT_NAME*.jar && echo `date` 'killed' >> log_$ARTIFACT_NAME" ssh $USERSERVER "cd /tmp && rm -rf $ARTIFACT_NAME*.jar && echo `date` 'killed' >> log_$ARTIFACT_NAME"
scp build/libs/$ARTIFACT_NAME-0.1.0-SNAPSHOT.jar $USERSERVER:/tmp/$ARTIFACT_NAME-0.1.0-SNAPSHOT.jar scp build/libs/$ARTIFACT_NAME-0.1.0-SNAPSHOT.jar $USERSERVER:/tmp/$ARTIFACT_NAME-0.1.0-SNAPSHOT.jar
ssh $USERSERVER -f "cd /tmp/ && /opt/jdk-11/bin/java -jar $ARTIFACT_NAME-0.1.0-SNAPSHOT.jar -Xms 512m -Xmx 1024m --server.port=8080 --server.http.port=8443 --ng-tracker.base-url=http://193.110.3.124:8080 --ng-tracker.dev-mode=false --ng-tracker.driver-path=/home/user >> /home/user/logfile_$ARTIFACT_NAME" & ssh $USERSERVER -f "cd /tmp/ && /opt/jdk1.8.0_192/bin/java -jar $ARTIFACT_NAME-0.1.0-SNAPSHOT.jar -Xms 512m -Xmx 1024m --server.port=8443 --server.http.port=8080 --ng-tracker.base-url=http://193.110.3.124:8080 >> /home/user/logfile_$ARTIFACT_NAME" &
sleep 10 sleep 10
echo "is deployed" echo "is deployed"

View File

@ -2,6 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true

View File

@ -2,30 +2,13 @@ package ru.ulstu;
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.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import ru.ulstu.configuration.ApplicationProperties;
import ru.ulstu.core.repository.JpaDetachableRepositoryImpl; import ru.ulstu.core.repository.JpaDetachableRepositoryImpl;
@SpringBootApplication @SpringBootApplication
@EnableJpaRepositories(repositoryBaseClass = JpaDetachableRepositoryImpl.class) @EnableJpaRepositories(repositoryBaseClass = JpaDetachableRepositoryImpl.class)
public class NgTrackerApplication { public class NgTrackerApplication {
private final ApplicationProperties applicationProperties;
public NgTrackerApplication(ApplicationProperties applicationProperties) {
this.applicationProperties = applicationProperties;
}
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(NgTrackerApplication.class, args); SpringApplication.run(NgTrackerApplication.class, args);
} }
@EventListener(ApplicationReadyEvent.class)
public void doSomethingAfterStartup() {
System.out.println("hello world, I have just started up");
if (applicationProperties.isCheckRun()) {
System.exit(0);
}
}
} }

View File

@ -4,17 +4,20 @@ 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.commit.model.CommitListDto;
import ru.ulstu.commit.service.CommitService;
import ru.ulstu.configuration.Constants; import ru.ulstu.configuration.Constants;
import ru.ulstu.core.model.response.PageableItems; import ru.ulstu.core.model.response.PageableItems;
import ru.ulstu.commit.model.CommitListDto;
import ru.ulstu.commit.service.CommitService;
import ru.ulstu.core.model.response.Response; import ru.ulstu.core.model.response.Response;
import ru.ulstu.odin.controller.OdinController; import ru.ulstu.odin.controller.OdinController;
import ru.ulstu.odin.model.OdinVoid; import ru.ulstu.odin.model.OdinVoid;
import static ru.ulstu.commit.controller.CommitController.URL;
@RestController @RestController
@RequestMapping(Constants.API_1_0 + "commits") @RequestMapping(URL)
public class CommitController extends OdinController<CommitListDto, OdinVoid> { public class CommitController extends OdinController<CommitListDto, OdinVoid> {
public static final String URL = Constants.API_1_0 + "commits";
private final CommitService commitService; private final CommitService commitService;
public CommitController(CommitService commitService) { public CommitController(CommitService commitService) {

View File

@ -1,165 +0,0 @@
package ru.ulstu.conference.controller;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import ru.ulstu.conference.model.ConferenceDto;
import ru.ulstu.conference.model.ConferenceFilterDto;
import ru.ulstu.conference.model.ConferenceUser;
import ru.ulstu.conference.service.ConferenceService;
import ru.ulstu.user.model.User;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import static ru.ulstu.core.controller.Navigation.CONFERENCES_PAGE;
import static ru.ulstu.core.controller.Navigation.CONFERENCE_PAGE;
import static ru.ulstu.core.controller.Navigation.REDIRECT_TO;
@Controller()
@RequestMapping(value = "/conferences")
@Hidden
public class ConferenceController {
private final ConferenceService conferenceService;
public ConferenceController(ConferenceService conferenceService) {
this.conferenceService = conferenceService;
}
@GetMapping("/conferences")
public void getConferences(ModelMap modelMap) {
modelMap.put("filteredConferences", new ConferenceFilterDto(conferenceService.findAllDto()));
}
@PostMapping("/conferences")
public void filterConferences(@Valid ConferenceFilterDto conferenceFilterDto, ModelMap modelMap) {
modelMap.put("filteredConferences", new ConferenceFilterDto(conferenceService.filter(conferenceFilterDto),
conferenceFilterDto.getFilterUserId(),
conferenceFilterDto.getYear()));
}
@GetMapping("/dashboard")
public void getDashboard(ModelMap modelMap) {
modelMap.put("conferences", conferenceService.findAllActiveDto());
conferenceService.setChartData(modelMap); // example
}
@GetMapping("/conference")
public void getConference(ModelMap modelMap, @RequestParam(value = "id") Integer id) {
if (id != null && id > 0) {
modelMap.put("conferenceDto", conferenceService.getExistConferenceById(id));
} else {
modelMap.put("conferenceDto", conferenceService.getNewConference());
}
}
@PostMapping(value = "/conferences", params = "deleteConference")
public String delete(@RequestParam("deleteConference") Integer conferenceId) throws IOException {
conferenceService.delete(conferenceId);
return String.format(REDIRECT_TO, CONFERENCES_PAGE);
}
@PostMapping(value = "/conference", params = "save")
public String save(@Valid ConferenceDto conferenceDto, Errors errors) throws IOException {
if (!conferenceService.save(conferenceDto, errors)) {
return CONFERENCE_PAGE;
}
return String.format(REDIRECT_TO, CONFERENCES_PAGE);
}
@PostMapping(value = "/conference", params = "addDeadline")
public String addDeadline(@Valid ConferenceDto conferenceDto, Errors errors) throws IOException {
conferenceService.filterEmptyDeadlines(conferenceDto);
if (errors.hasErrors()) {
return CONFERENCE_PAGE;
}
conferenceService.addDeadline(conferenceDto);
return CONFERENCE_PAGE;
}
@PostMapping(value = "/conference", params = "removeDeadline")
public String removeDeadline(@Valid ConferenceDto conferenceDto, Errors errors,
@RequestParam(value = "removeDeadline") Integer deadlineIndex) throws IOException {
if (errors.hasErrors()) {
return CONFERENCE_PAGE;
}
conferenceService.removeDeadline(conferenceDto, deadlineIndex);
return CONFERENCE_PAGE;
}
@PostMapping(value = "/conference", params = "addPaper")
public String addPaper(@Valid ConferenceDto conferenceDto, Errors errors) throws IOException {
if (errors.hasErrors()) {
return CONFERENCE_PAGE;
}
conferenceService.addPaper(conferenceDto);
return CONFERENCE_PAGE;
}
@PostMapping(value = "/conference", params = "removePaper")
public String removePaper(@Valid ConferenceDto conferenceDto, Errors errors,
@RequestParam(value = "removePaper") Integer paperIndex) throws IOException {
if (errors.hasErrors()) {
return CONFERENCE_PAGE;
}
conferenceService.removePaper(conferenceDto, paperIndex);
return CONFERENCE_PAGE;
}
@PostMapping(value = "/conference", params = "takePart")
public String takePart(@Valid ConferenceDto conferenceDto, Errors errors) throws IOException {
if (errors.hasErrors()) {
return CONFERENCE_PAGE;
}
conferenceService.takePart(conferenceDto);
return CONFERENCE_PAGE;
}
@PostMapping(value = "/conference", params = "pingConference")
public String ping(@Valid ConferenceDto conferenceDto, Errors errors) throws IOException {
if (errors.hasErrors()) {
return CONFERENCE_PAGE;
}
conferenceService.ping(conferenceDto);
return CONFERENCE_PAGE;
}
@ModelAttribute("allParticipation")
public List<ConferenceUser.Participation> getAllParticipation() {
return conferenceService.getAllParticipations();
}
@ModelAttribute("allDeposit")
public List<ConferenceUser.Deposit> getAllDeposit() {
return conferenceService.getAllDeposit();
}
@ModelAttribute("allUsers")
public List<User> getAllUsers() {
return conferenceService.getAllUsers();
}
@ModelAttribute("allYears")
public List<Integer> getAllYears() {
List<Integer> years = new ArrayList<>();
for (int i = Calendar.getInstance().get(Calendar.YEAR); i > 2010; i--) {
years.add(i);
}
return years;
}
}

View File

@ -1,177 +0,0 @@
package ru.ulstu.conference.model;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderBy;
import jakarta.persistence.Table;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import jakarta.validation.constraints.NotBlank;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.springframework.format.annotation.DateTimeFormat;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.core.model.EventSource;
import ru.ulstu.core.model.UserActivity;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.timeline.model.Event;
import ru.ulstu.user.model.User;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@Entity
@Table(name = "conference")
@DiscriminatorValue("CONFERENCE")
public class Conference extends BaseEntity implements UserActivity, EventSource {
@NotBlank
private String title;
private String description;
private String url;
private int ping = 0;
@Column(name = "begin_date")
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date beginDate = new Date();
@Column(name = "end_date")
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endDate = new Date();
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "conference_id", unique = true)
@Fetch(FetchMode.SUBSELECT)
@OrderBy("date")
private List<Deadline> deadlines = new ArrayList<>();
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
@JoinColumn(name = "conference_id")
private List<Paper> papers = new ArrayList<>();
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "conference_id", unique = true)
private List<ConferenceUser> users = new ArrayList<>();
public Conference() {
}
public Conference(@NotBlank String title) {
this.title = title;
}
public String getTitle() {
return title;
}
@Override
public List<User> getRecipients() {
List<User> list = new ArrayList<>();
getUsers().forEach(conferenceUser -> list.add(conferenceUser.getUser()));
return list;
}
@Override
public void addObjectToEvent(Event event) {
event.setConference(this);
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getPing() {
return ping;
}
public void setPing(int ping) {
this.ping = ping;
}
public Date getBeginDate() {
return beginDate;
}
public void setBeginDate(Date beginDate) {
this.beginDate = beginDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public List<Deadline> getDeadlines() {
return deadlines;
}
public void setDeadlines(List<Deadline> deadlines) {
this.deadlines = deadlines;
}
public List<Paper> getPapers() {
return papers;
}
public void setPapers(List<Paper> papers) {
this.papers = papers;
}
public List<ConferenceUser> getUsers() {
return users;
}
public void setUsers(List<ConferenceUser> users) {
this.users = users;
}
public Optional<Deadline> getNextDeadline() {
return deadlines
.stream()
.filter(deadline -> deadline.getDate() != null)
.sorted(Comparator.comparing(Deadline::getDate))
.filter(d -> d.getDate().after(new Date()))
.findFirst();
}
@Override
public Set<User> getActivityUsers() {
return getUsers().stream().map(ConferenceUser::getUser).collect(Collectors.toSet());
}
}

View File

@ -1,253 +0,0 @@
package ru.ulstu.conference.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
import org.springframework.format.annotation.DateTimeFormat;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.name.NameContainer;
import ru.ulstu.paper.model.Paper;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import static ru.ulstu.core.util.StreamApiUtils.convert;
public class ConferenceDto extends NameContainer {
private final static String BEGIN_DATE = "Начало: ";
private final static String END_DATE = "Конец: ";
private Integer id;
@NotEmpty
@Size(min = 2, max = 400)
private String title;
@Size(max = 500)
private String description = "";
@Size(max = 255)
private String url = "";
private int ping = 0;
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date beginDate = new Date();
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endDate = new Date();
private List<Deadline> deadlines = new ArrayList<>();
private List<Integer> removedDeadlineIds = new ArrayList<>();
private List<Integer> userIds = new ArrayList<>();
private List<Integer> paperIds = new ArrayList<>();
private List<Paper> papers = new ArrayList<>();
private List<Paper> notSelectedPapers = new ArrayList<>();
private List<ConferenceUser> users = new ArrayList<>();
private boolean disabledTakePart = false;
public ConferenceDto() {
}
@JsonCreator
public ConferenceDto(@JsonProperty("id") Integer id,
@JsonProperty("title") String title,
@JsonProperty("description") String description,
@JsonProperty("url") String url,
@JsonProperty("ping") Integer ping,
@JsonProperty("beginDate") Date beginDate,
@JsonProperty("endDate") Date endDate,
@JsonProperty("deadlines") List<Deadline> deadlines,
@JsonProperty("userIds") List<Integer> userIds,
@JsonProperty("paperIds") List<Integer> paperIds,
@JsonProperty("users") List<ConferenceUser> users,
@JsonProperty("papers") List<Paper> papers,
@JsonProperty("notSelectedPapers") List<Paper> notSelectedPapers,
@JsonProperty("notSelectedPapers") Boolean disabledTakePart) {
this.id = id;
this.title = title;
this.description = description;
this.url = url;
this.ping = ping;
this.beginDate = beginDate;
this.endDate = endDate;
this.deadlines = deadlines;
this.userIds = userIds;
this.paperIds = paperIds;
this.users = users;
this.papers = papers;
this.notSelectedPapers = notSelectedPapers;
this.disabledTakePart = disabledTakePart;
}
public ConferenceDto(Conference conference) {
this.id = conference.getId();
this.title = conference.getTitle();
this.description = conference.getDescription();
this.url = conference.getUrl();
this.ping = conference.getPing();
this.beginDate = conference.getBeginDate();
this.endDate = conference.getEndDate();
this.deadlines = conference.getDeadlines();
this.userIds = convert(conference.getUsers(), BaseEntity::getId);
this.paperIds = convert(conference.getPapers(), BaseEntity::getId);
this.users = conference.getUsers();
this.papers = conference.getPapers();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getPing() {
return ping;
}
public void setPing(int ping) {
this.ping = ping;
}
public Date getBeginDate() {
return beginDate;
}
public void setBeginDate(Date beginDate) {
this.beginDate = beginDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public List<Deadline> getDeadlines() {
return deadlines;
}
public void setDeadlines(List<Deadline> deadlines) {
this.deadlines = deadlines;
}
public List<Integer> getUserIds() {
return userIds;
}
public void setUserIds(List<Integer> userIds) {
this.userIds = userIds;
}
public List<Integer> getPaperIds() {
return paperIds;
}
public void setPaperIds(List<Integer> paperIds) {
this.paperIds = paperIds;
}
public List<Paper> getPapers() {
return papers;
}
public void setPapers(List<Paper> papers) {
this.papers = papers;
}
public List<ConferenceUser> getUsers() {
return users;
}
public void setUsers(List<ConferenceUser> users) {
this.users = users;
}
public boolean isDisabledTakePart() {
return disabledTakePart;
}
public void setDisabledTakePart(boolean disabledTakePart) {
this.disabledTakePart = disabledTakePart;
}
public List<Integer> getRemovedDeadlineIds() {
return removedDeadlineIds;
}
public void setRemovedDeadlineIds(List<Integer> removedDeadlineIds) {
this.removedDeadlineIds = removedDeadlineIds;
}
public List<Paper> getNotSelectedPapers() {
return notSelectedPapers;
}
public void setNotSelectedPapers(List<Paper> notSelectedPapers) {
this.notSelectedPapers = notSelectedPapers;
}
public String getDatesString() {
return BEGIN_DATE + beginDate.toString().split(" ")[0] + " " + END_DATE + endDate.toString().split(" ")[0];
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ConferenceDto that = (ConferenceDto) o;
return ping == that.ping &&
disabledTakePart == that.disabledTakePart &&
Objects.equals(id, that.id) &&
Objects.equals(title, that.title) &&
Objects.equals(description, that.description) &&
Objects.equals(url, that.url) &&
Objects.equals(deadlines, that.deadlines) &&
Objects.equals(removedDeadlineIds, that.removedDeadlineIds) &&
Objects.equals(userIds, that.userIds) &&
Objects.equals(paperIds, that.paperIds) &&
Objects.equals(papers, that.papers) &&
Objects.equals(notSelectedPapers, that.notSelectedPapers) &&
Objects.equals(users, that.users);
}
@Override
public int hashCode() {
return Objects.hash(id, title, description, url, ping, beginDate, endDate, deadlines, removedDeadlineIds,
userIds, paperIds, papers, notSelectedPapers, users, disabledTakePart);
}
}

View File

@ -1,47 +0,0 @@
package ru.ulstu.conference.model;
import java.util.List;
public class ConferenceFilterDto {
private List<ConferenceDto> conferences;
private Integer filterUserId;
private Integer year;
public ConferenceFilterDto() {
}
public ConferenceFilterDto(List<ConferenceDto> conferences, Integer filterUserId, Integer year) {
this.conferences = conferences;
this.filterUserId = filterUserId;
this.year = year;
}
public ConferenceFilterDto(List<ConferenceDto> conferences) {
this(conferences, null, null);
}
public List<ConferenceDto> getConferences() {
return conferences;
}
public void setConferences(List<ConferenceDto> conferences) {
this.conferences = conferences;
}
public Integer getFilterUserId() {
return filterUserId;
}
public void setFilterUserId(Integer filterUserId) {
this.filterUserId = filterUserId;
}
public Integer getYear() {
return year;
}
public void setYear(Integer year) {
this.year = year;
}
}

View File

@ -1,110 +0,0 @@
package ru.ulstu.conference.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.user.model.User;
@Entity
@Table(name = "users_conference")
public class ConferenceUser extends BaseEntity {
public enum Participation {
INTRAMURAL("Очная"),
EXTRAMURAL("Заочная");
private final String participationName;
Participation(String name) {
this.participationName = name;
}
public String getParticipation() {
return participationName;
}
}
public enum Deposit {
ARTICLE("Статья"),
REPORT("Доклад"),
PRESENTATION("Презентация");
private final String depositName;
Deposit(String name) {
this.depositName = name;
}
public String getDeposit() {
return depositName;
}
}
@NotNull
@Column(name = "participation", nullable = false)
@Enumerated(value = EnumType.STRING)
private Participation participation = Participation.INTRAMURAL;
@NotNull
@Column(name = "deposit", nullable = false)
@Enumerated(value = EnumType.STRING)
private Deposit deposit = Deposit.ARTICLE;
@ManyToOne(optional = false)
@JoinColumn(name = "users_id")
private User user;
public ConferenceUser() {
}
public ConferenceUser(User user) {
this.user = user;
this.deposit = Deposit.REPORT;
}
@JsonCreator
public ConferenceUser(@JsonProperty("id") Integer id,
@JsonProperty("deposit") Participation participation,
@JsonProperty("deposit") Deposit deposit,
@JsonProperty("user") User user) {
this.setId(id);
this.participation = participation;
this.deposit = deposit;
this.user = user;
}
public Participation getParticipation() {
return participation;
}
public void setParticipation(Participation participation) {
this.participation = participation;
}
public Deposit getDeposit() {
return deposit;
}
public void setDeposit(Deposit deposit) {
this.deposit = deposit;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}

View File

@ -1,36 +0,0 @@
package ru.ulstu.conference.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.name.BaseRepository;
import ru.ulstu.user.model.User;
import java.util.Date;
import java.util.List;
public interface ConferenceRepository extends JpaRepository<Conference, Integer>, BaseRepository {
@Query("SELECT c FROM Conference c LEFT JOIN c.users u WHERE (:user IS NULL OR u.user = :user) " +
"AND (YEAR(c.beginDate) = :year OR :year IS NULL) ORDER BY c.beginDate DESC")
List<Conference> findByUserAndYear(@Param("user") User user, @Param("year") Integer year);
@Query("SELECT c FROM Conference c WHERE c.beginDate > :date")
List<Conference> findAllActive(@Param("date") Date date);
@Query("SELECT case when count(c) > 0 then true else false end FROM Conference c JOIN c.papers p WHERE p.id = :paperId")
boolean isPaperAttached(@Param("paperId") Integer paperId);
@Modifying
@Query("UPDATE Conference c SET c.ping = (c.ping + 1) WHERE c.id = :id")
int updatePingConference(@Param("id") Integer id);
@Override
@Query("SELECT title FROM Conference c WHERE (c.title = :name) AND (:id IS NULL OR c.id != :id) ")
List<String> findByNameAndNotId(@Param("name") String name, @Param("id") Integer id);
@Query("SELECT c FROM Conference c LEFT JOIN c.users u WHERE (:user IS NULL OR u.user = :user) " +
"AND (u.participation = 'INTRAMURAL') AND (c.beginDate <= CURRENT_DATE) AND (c.endDate >= CURRENT_DATE)")
Conference findActiveByUser(@Param("user") User user);
}

View File

@ -1,7 +0,0 @@
package ru.ulstu.conference.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ulstu.conference.model.ConferenceUser;
public interface ConferenceUserRepository extends JpaRepository<ConferenceUser, Integer> {
}

View File

@ -1,112 +0,0 @@
package ru.ulstu.conference.service;
import org.springframework.stereotype.Service;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.core.util.DateUtils;
import ru.ulstu.ping.service.PingService;
import ru.ulstu.user.service.MailService;
import ru.ulstu.user.service.UserService;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
public class ConferenceNotificationService {
private final static int YESTERDAY = -1;
private final static int DAYS_TO_DEADLINE_NOTIFICATION = 7;
private final static String TEMPLATE_PING = "conferencePingNotification";
private final static String TEMPLATE_DEADLINE = "conferenceDeadlineNotification";
private final static String TEMPLATE_CREATE = "conferenceCreateNotification";
private final static String TEMPLATE_UPDATE_DEADLINES = "conferenceUpdateDeadlinesNotification";
private final static String TEMPLATE_UPDATE_DATES = "conferenceUpdateDatesNotification";
private final static String TITLE_PING = "Обратите внимание на конференцию: %s";
private final static String TITLE_DEADLINE = "Приближается дедлайн конференции: %s";
private final static String TITLE_CREATE = "Создана новая конференция: %s";
private final static String TITLE_UPDATE_DEADLINES = "Изменения дедлайнов в конференции: %s";
private final static String TITLE_UPDATE_DATES = "Изменение дат проведения конференции: %s";
private final MailService mailService;
private final UserService userService;
private final PingService pingService;
public ConferenceNotificationService(MailService mailService,
UserService userService,
PingService pingService) {
this.mailService = mailService;
this.userService = userService;
this.pingService = pingService;
}
public void sendDeadlineNotifications(List<Conference> conferences) {
Date now = DateUtils.addDays(new Date(), DAYS_TO_DEADLINE_NOTIFICATION);
conferences
.stream()
.filter(conference -> needToSendDeadlineNotification(conference, now))
.forEach(this::sendMessageDeadline);
}
private boolean needToSendDeadlineNotification(Conference conference, Date compareDate) {
return (conference.getNextDeadline().isPresent())
&& conference.getNextDeadline().get().getDate().after(new Date())
&& conference.getNextDeadline().get().getDate().before(compareDate);
}
private void sendMessageDeadline(Conference conference) {
Map<String, Object> variables = Map.of("conference", conference);
sendForAllParticipants(variables, conference, TEMPLATE_DEADLINE, String.format(TITLE_DEADLINE, conference.getTitle()));
}
public void sendCreateNotification(Conference conference) {
Map<String, Object> variables = Map.of("conference", conference);
sendForAllUsers(variables, String.format(TITLE_CREATE, conference.getTitle()));
}
public void updateDeadlineNotification(Conference conference) {
Map<String, Object> variables = Map.of("conference", conference);
sendForAllParticipants(variables, conference, TEMPLATE_UPDATE_DEADLINES, String.format(TITLE_UPDATE_DEADLINES, conference.getTitle()));
}
public void updateConferencesDatesNotification(Conference conference, Date oldBeginDate, Date oldEndDate) {
Map<String, Object> variables = Map.of("conference", conference, "oldBeginDate", oldBeginDate, "oldEndDate", oldEndDate);
sendForAllParticipants(variables, conference, TEMPLATE_UPDATE_DATES, String.format(TITLE_UPDATE_DATES, conference.getTitle()));
}
private void sendForAllUsers(Map<String, Object> variables, String title) {
userService.findAll().forEach(user -> mailService.sendEmailFromTemplate(variables, user, ConferenceNotificationService.TEMPLATE_CREATE, title));
}
private void sendForAllParticipants(Map<String, Object> variables, Conference conference, String template, String title) {
conference.getUsers().forEach(conferenceUser -> mailService.sendEmailFromTemplate(variables, conferenceUser.getUser(), template, title));
}
public void sendPingNotifications(List<Conference> conferences) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.DAY_OF_MONTH, YESTERDAY);
conferences
.stream()
.filter(conference -> {
Integer pingCount = pingService.countPingYesterday(conference, calendar);
return needToSendPingNotification(conference, pingCount);
})
.forEach(this::sendMessagePing);
}
private boolean needToSendPingNotification(Conference conference, Integer pingCount) {
if (pingCount > 0) {
conference.setPing((Integer) pingCount);
return true;
}
return false;
}
private void sendMessagePing(Conference conference) {
Map<String, Object> variables = Map.of("conference", conference);
sendForAllParticipants(variables, conference, TEMPLATE_PING, String.format(TITLE_PING, conference.getTitle()));
}
}

View File

@ -1,37 +0,0 @@
package ru.ulstu.conference.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
public class ConferenceScheduler {
private final static boolean IS_DEADLINE_NOTIFICATION_BEFORE_WEEK = true;
private final Logger log = LoggerFactory.getLogger(ConferenceScheduler.class);
private final ConferenceNotificationService conferenceNotificationService;
private final ConferenceService conferenceService;
public ConferenceScheduler(ConferenceNotificationService conferenceNotificationService,
ConferenceService conferenceService) {
this.conferenceNotificationService = conferenceNotificationService;
this.conferenceService = conferenceService;
}
@Scheduled(cron = "0 0 8 * * MON", zone = "Europe/Samara")
public void checkDeadlineBeforeWeek() {
log.debug("ConferenceScheduler.checkDeadlineBeforeWeek started");
conferenceNotificationService.sendDeadlineNotifications(conferenceService.findAll());
log.debug("ConferenceScheduler.checkDeadlineBeforeWeek finished");
}
@Scheduled(cron = "0 0 8 * * *", zone = "Europe/Samara")
public void checkNewPing() {
log.debug("ConferenceScheduler.checkPing started");
conferenceNotificationService.sendPingNotifications(conferenceService.findAll());
log.debug("ConferenceScheduler.checkPing finished");
}
}

View File

@ -1,358 +0,0 @@
package ru.ulstu.conference.service;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.conference.model.ConferenceDto;
import ru.ulstu.conference.model.ConferenceFilterDto;
import ru.ulstu.conference.model.ConferenceUser;
import ru.ulstu.conference.repository.ConferenceRepository;
import ru.ulstu.core.util.DateUtils;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.deadline.service.DeadlineService;
import ru.ulstu.name.BaseService;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.service.PaperService;
import ru.ulstu.ping.service.PingService;
import ru.ulstu.timeline.service.EventService;
import ru.ulstu.user.model.User;
import ru.ulstu.user.service.UserService;
import java.io.IOException;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
import static org.springframework.util.ObjectUtils.isEmpty;
import static ru.ulstu.core.util.StreamApiUtils.convert;
@Service
public class ConferenceService extends BaseService {
private final static int MAX_DISPLAY_SIZE = 40;
private final ConferenceRepository conferenceRepository;
private final ConferenceUserService conferenceUserService;
private final DeadlineService deadlineService;
private final PaperService paperService;
private final UserService userService;
private final PingService pingService;
private final ConferenceNotificationService conferenceNotificationService;
private final EventService eventService;
public ConferenceService(ConferenceRepository conferenceRepository,
ConferenceUserService conferenceUserService,
DeadlineService deadlineService,
PaperService paperService,
UserService userService,
PingService pingService,
ConferenceNotificationService conferenceNotificationService,
EventService eventService) {
this.baseRepository = conferenceRepository;
this.conferenceRepository = conferenceRepository;
this.conferenceUserService = conferenceUserService;
this.deadlineService = deadlineService;
this.paperService = paperService;
this.userService = userService;
this.pingService = pingService;
this.conferenceNotificationService = conferenceNotificationService;
this.eventService = eventService;
}
public ConferenceDto getExistConferenceById(Integer id) {
ConferenceDto conferenceDto = new ConferenceDto(conferenceRepository.getOne(id));
conferenceDto.setNotSelectedPapers(getNotSelectPapers(conferenceDto.getPaperIds()));
conferenceDto.setDisabledTakePart(isCurrentUserParticipant(conferenceDto.getUsers()));
return conferenceDto;
}
public ConferenceDto getNewConference() {
ConferenceDto conferenceDto = new ConferenceDto();
conferenceDto.setNotSelectedPapers(getNotSelectPapers(new ArrayList<>()));
return conferenceDto;
}
public List<Conference> findAll() {
return conferenceRepository.findAll(Sort.by(Sort.Direction.DESC, "beginDate"));
}
public List<ConferenceDto> findAllDto() {
List<ConferenceDto> conferences = convert(findAll(), ConferenceDto::new);
conferences.forEach(conferenceDto -> conferenceDto.setTitle(StringUtils.abbreviate(conferenceDto.getTitle(), MAX_DISPLAY_SIZE)));
return conferences;
}
public boolean save(ConferenceDto conferenceDto, Errors errors) throws IOException {
conferenceDto.setName(conferenceDto.getTitle());
filterEmptyDeadlines(conferenceDto);
checkEmptyFieldsOfDeadline(conferenceDto, errors);
checkEmptyFieldsOfDates(conferenceDto, errors);
checkUniqueName(conferenceDto,
errors,
conferenceDto.getId(),
"Конференция с таким именем уже существует");
if (errors.hasErrors()) {
return false;
}
if (isEmpty(conferenceDto.getId())) {
create(conferenceDto);
} else {
update(conferenceDto);
}
return true;
}
public Conference save(Conference conference) {
if (isEmpty(conference.getId())) {
return create(conference);
} else {
return update(conference);
}
}
@Transactional
public Conference create(ConferenceDto conferenceDto) throws IOException {
return create(copyFromDto(new Conference(), conferenceDto));
}
@Transactional
public Conference create(Conference conference) {
conference = conferenceRepository.save(conference);
conferenceNotificationService.sendCreateNotification(conference);
return conference;
}
@Transactional
private Conference update(ConferenceDto conferenceDto) throws IOException {
return update(copyFromDto(conferenceRepository.getOne(conferenceDto.getId()), conferenceDto));
}
@Transactional
private Conference update(Conference conference) {
Conference oldConference = conferenceRepository.getOne(conference.getId());
List<Deadline> oldDeadlines = oldConference.getDeadlines().stream()
.map(this::copyDeadline)
.collect(Collectors.toList());
Date oldBeginDate = conference.getBeginDate();
Date oldEndDate = conference.getEndDate();
conferenceRepository.save(conference);
sendNotificationAfterUpdateDeadlines(conference, oldDeadlines);
if (!conference.getBeginDate().equals(oldBeginDate) || !conference.getEndDate().equals(oldEndDate)) {
conferenceNotificationService.updateConferencesDatesNotification(conference, oldBeginDate, oldEndDate);
}
return conference;
}
@Transactional
public boolean delete(Integer conferenceId) {
if (conferenceRepository.existsById(conferenceId)) {
eventService.removeConferencesEvent(conferenceRepository.getOne(conferenceId));
conferenceRepository.deleteById(conferenceId);
return true;
}
return false;
}
@Transactional
public boolean delete(List<Conference> conferences) {
conferences.forEach(conference -> delete(conference.getId()));
return true;
}
public ConferenceDto addDeadline(ConferenceDto conferenceDto) {
conferenceDto.getDeadlines().add(new Deadline());
return conferenceDto;
}
public ConferenceDto removeDeadline(ConferenceDto conferenceDto, Integer deadlineIndex) throws IOException {
if (conferenceDto.getDeadlines().get(deadlineIndex).getId() != null) {
conferenceDto.getRemovedDeadlineIds().add(conferenceDto.getDeadlines().get(deadlineIndex).getId());
}
conferenceDto.getDeadlines().remove((int) deadlineIndex);
return conferenceDto;
}
public ConferenceDto addPaper(ConferenceDto conferenceDto) {
Paper paper = new Paper();
paper.setTitle(userService.getCurrentUser().getLastName() + "_" + conferenceDto.getTitle() + "_" + (new Date()).getTime());
paper.setStatus(Paper.PaperStatus.DRAFT);
conferenceDto.getPapers().add(paper);
return conferenceDto;
}
public ConferenceDto removePaper(ConferenceDto conferenceDto, Integer paperIndex) throws IOException {
Paper removedPaper = conferenceDto.getPapers().remove((int) paperIndex);
if (removedPaper.getId() != null) {
conferenceDto.getNotSelectedPapers().add(removedPaper);
}
return conferenceDto;
}
public ConferenceDto takePart(ConferenceDto conferenceDto) throws IOException {
conferenceDto.getUsers().add(new ConferenceUser(userService.getCurrentUser()));
conferenceDto.setDisabledTakePart(true);
return conferenceDto;
}
private List<Paper> getNotSelectPapers(List<Integer> paperIds) {
return paperService.findAllNotSelect(paperIds);
}
public List<User> getAllUsers() {
return userService.findAll();
}
public List<ConferenceUser.Participation> getAllParticipations() {
return Arrays.asList(ConferenceUser.Participation.values());
}
public List<ConferenceUser.Deposit> getAllDeposit() {
return Arrays.asList(ConferenceUser.Deposit.values());
}
private Conference copyFromDto(Conference conference, ConferenceDto conferenceDto) throws IOException {
conference.setTitle(conferenceDto.getTitle());
conference.setDescription(conferenceDto.getDescription());
conference.setUrl(conferenceDto.getUrl());
conference.setBeginDate(conferenceDto.getBeginDate());
conference.setEndDate(conferenceDto.getEndDate());
conference.getPapers().clear();
conferenceDto.getPapers().forEach(paper -> conference.getPapers().add(paper.getId() != null ? paperService.findPaperById(paper.getId()) : paperService.create(paper)));
conference.setDeadlines(deadlineService.saveOrCreate(conferenceDto.getDeadlines()));
conference.setUsers(conferenceUserService.saveOrCreate(conferenceDto.getUsers()));
if (conferenceDto.getPaperIds() != null && !conferenceDto.getPaperIds().isEmpty()) {
conferenceDto.getPaperIds().forEach(paperId ->
conference.getPapers().add(paperService.findPaperById(paperId)));
}
return conference;
}
private boolean isCurrentUserParticipant(List<ConferenceUser> conferenceUsers) {
return conferenceUsers.stream().anyMatch(participant -> participant.getUser().equals(userService.getCurrentUser()));
}
public List<ConferenceDto> filter(ConferenceFilterDto conferenceFilterDto) {
return convert(conferenceRepository.findByUserAndYear(
conferenceFilterDto.getFilterUserId() == null ? null : userService.findById(conferenceFilterDto.getFilterUserId()),
conferenceFilterDto.getYear()), ConferenceDto::new);
}
public List<ConferenceDto> findAllActiveDto() {
return convert(findAllActive(), ConferenceDto::new);
}
public List<Conference> findAllActive() {
return conferenceRepository.findAllActive(new Date());
}
public boolean isAttachedToConference(Integer paperId) {
return conferenceRepository.isPaperAttached(paperId);
}
@Transactional
public void ping(ConferenceDto conferenceDto) throws IOException {
pingService.addPing(findOne(conferenceDto.getId()));
conferenceRepository.updatePingConference(conferenceDto.getId());
}
public Conference findOne(Integer conferenceId) {
return conferenceRepository.getOne(conferenceId);
}
public void setChartData(ModelMap modelMap) {
//first, add the regional sales
Integer northeastSales = 17089;
Integer westSales = 10603;
Integer midwestSales = 5223;
Integer southSales = 10111;
modelMap.addAttribute("northeastSales", northeastSales);
modelMap.addAttribute("southSales", southSales);
modelMap.addAttribute("midwestSales", midwestSales);
modelMap.addAttribute("westSales", westSales);
//now add sales by lure type
List<Integer> inshoreSales = Arrays.asList(4074, 3455, 4112);
List<Integer> nearshoreSales = Arrays.asList(3222, 3011, 3788);
List<Integer> offshoreSales = Arrays.asList(7811, 7098, 6455);
modelMap.addAttribute("inshoreSales", inshoreSales);
modelMap.addAttribute("nearshoreSales", nearshoreSales);
modelMap.addAttribute("offshoreSales", offshoreSales);
}
private void sendNotificationAfterUpdateDeadlines(Conference conference, List<Deadline> oldDeadlines) {
if (oldDeadlines.size() != conference.getDeadlines().size()) {
conferenceNotificationService.updateDeadlineNotification(conference);
return;
}
if (conference.getDeadlines()
.stream()
.filter(deadline -> !oldDeadlines.contains(deadline))
.count() > 0) {
conferenceNotificationService.updateDeadlineNotification(conference);
}
}
private Deadline copyDeadline(Deadline oldDeadline) {
Deadline newDeadline = new Deadline(oldDeadline.getDate(), oldDeadline.getDescription());
newDeadline.setId(oldDeadline.getId());
return newDeadline;
}
private void checkEmptyFieldsOfDeadline(ConferenceDto conferenceDto, Errors errors) {
for (Deadline deadline : conferenceDto.getDeadlines()) {
if (deadline.getDate() == null || deadline.getDescription().isEmpty()) {
errors.rejectValue("deadlines", "errorCode", "Все поля дедлайна должны быть заполнены");
}
}
}
private void checkEmptyFieldsOfDates(ConferenceDto conferenceDto, Errors errors) {
if (conferenceDto.getBeginDate() == null || conferenceDto.getEndDate() == null) {
errors.rejectValue("beginDate", "errorCode", "Даты должны быть заполнены");
}
}
public void filterEmptyDeadlines(ConferenceDto conferenceDto) {
conferenceDto.setDeadlines(conferenceDto.getDeadlines().stream()
.filter(dto -> dto.getDate() != null || !org.springframework.util.StringUtils.isEmpty(dto.getDescription()))
.collect(Collectors.toList()));
}
public Conference getActiveConferenceByUser(User user) {
return conferenceRepository.findActiveByUser(user);
}
public Conference createByTitle(String newConferenceTitle) {
Conference conference = new Conference(newConferenceTitle);
conference.setBeginDate(DateUtils.localDateToDate(DateUtils.convertToLocalDate(new Date()).plus(1, ChronoUnit.WEEKS)));
conference.setEndDate(DateUtils.localDateToDate(DateUtils.convertToLocalDate(new Date()).plus(2, ChronoUnit.WEEKS)));
conference.getUsers().add(new ConferenceUser(userService.getCurrentUser()));
conference.getDeadlines().add(deadlineService.createWithOffset(new Date(), 1, ChronoUnit.WEEKS));
return save(conference);
}
public List<Conference> findAllActiveByCurrentUser() {
return findAllActive()
.stream()
.filter(conference -> conference.getUsers()
.stream()
.anyMatch(user -> user.getUser().equals(userService.getCurrentUser())))
.collect(toList());
}
}

View File

@ -1,46 +0,0 @@
package ru.ulstu.conference.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.ulstu.conference.model.ConferenceUser;
import ru.ulstu.conference.repository.ConferenceUserRepository;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class ConferenceUserService {
private final ConferenceUserRepository conferenceUserRepository;
public ConferenceUserService(ConferenceUserRepository conferenceUserRepository) {
this.conferenceUserRepository = conferenceUserRepository;
}
public List<ConferenceUser> saveOrCreate(List<ConferenceUser> users) {
return users
.stream()
.map(user -> {
return user.getId() != null ? update(user) : create(user);
}).collect(Collectors.toList());
}
@Transactional
private ConferenceUser update(ConferenceUser user) {
ConferenceUser updateUser = conferenceUserRepository.getOne(user.getId());
updateUser.setDeposit(user.getDeposit());
updateUser.setParticipation(user.getParticipation());
conferenceUserRepository.save(updateUser);
return updateUser;
}
@Transactional
private ConferenceUser create(ConferenceUser user) {
ConferenceUser newUser = new ConferenceUser();
newUser.setDeposit(user.getDeposit());
newUser.setParticipation(user.getParticipation());
newUser.setUser(user.getUser());
newUser = conferenceUserRepository.save(newUser);
return newUser;
}
}

View File

@ -1,6 +1,6 @@
package ru.ulstu.configuration; package ru.ulstu.configuration;
import jakarta.validation.constraints.NotBlank; import org.hibernate.validator.constraints.NotBlank;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -11,20 +11,12 @@ import org.springframework.validation.annotation.Validated;
public class ApplicationProperties { public class ApplicationProperties {
@NotBlank @NotBlank
private String baseUrl; private String baseUrl;
@NotBlank @NotBlank
private String undeadUserLogin; private String undeadUserLogin;
private boolean devMode; private boolean devMode;
private boolean useHttps; private boolean useHttps;
private boolean checkRun;
private String debugEmail;
private String driverPath;
public boolean isUseHttps() { public boolean isUseHttps() {
return useHttps; return useHttps;
} }
@ -56,28 +48,4 @@ public class ApplicationProperties {
public void setDevMode(boolean devMode) { public void setDevMode(boolean devMode) {
this.devMode = devMode; this.devMode = devMode;
} }
public boolean isCheckRun() {
return checkRun;
}
public void setCheckRun(boolean checkRun) {
this.checkRun = checkRun;
}
public String getDebugEmail() {
return debugEmail;
}
public void setDebugEmail(String debugEmail) {
this.debugEmail = debugEmail;
}
public String getDriverPath() {
return driverPath;
}
public void setDriverPath(String driverPath) {
this.driverPath = driverPath;
}
} }

View File

@ -5,21 +5,16 @@ public class Constants {
public static final String MAIL_ACTIVATE = "Account activation"; public static final String MAIL_ACTIVATE = "Account activation";
public static final String MAIL_RESET = "Password reset"; public static final String MAIL_RESET = "Password reset";
public static final String MAIL_INVITE = "Account registration";
public static final String MAIL_CHANGE_PASSWORD = "Password has been changed";
public static final int MIN_PASSWORD_LENGTH = 6; public static final int MIN_PASSWORD_LENGTH = 6;
public static final int MAX_PASSWORD_LENGTH = 32;
public static final String LOGIN_REGEX = "^[_'.@A-Za-z0-9-]*$"; public static final String LOGIN_REGEX = "^[_'.@A-Za-z0-9-]*$";
public static final String COOKIES_NAME = "JSESSIONID"; public static final String COOKIES_NAME = "JSESSIONID";
public static final String LOGOUT_URL = "/login?logout"; public static final String LOGOUT_URL = "/login";
public static final String SESSION_ID_ATTR = "sessionId"; public static final String SESSION_ID_ATTR = "sessionId";
public static final int SESSION_TIMEOUT_SECONDS = 30 * 60; public static final int SESSION_TIMEOUT_SECONDS = 30 * 60;
public static final String PASSWORD_RESET_REQUEST_PAGE = "/resetRequest"; public static final String PASSWORD_RESET_REQUEST_PAGE = "/resetRequest";
public static final String PASSWORD_RESET_PAGE = "/reset"; public static final String PASSWORD_RESET_PAGE = "/reset";
public static final int RESET_KEY_LENGTH = 6;
} }

View File

@ -0,0 +1,30 @@
package ru.ulstu.configuration;
import org.eclipse.jetty.server.ServerConnector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpListenerConfiguration implements EmbeddedServletContainerCustomizer {
@Value("${server.http.port}")
private int httpPort;
private void configureJetty(JettyEmbeddedServletContainerFactory jettyFactory) {
jettyFactory.addServerCustomizers((JettyServerCustomizer) server -> {
ServerConnector serverConnector = new ServerConnector(server);
serverConnector.setPort(httpPort);
server.addConnector(serverConnector);
});
}
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
if (container instanceof JettyEmbeddedServletContainerFactory) {
configureJetty((JettyEmbeddedServletContainerFactory) container);
}
}
}

View File

@ -1,10 +1,10 @@
package ru.ulstu.configuration; package ru.ulstu.configuration;
import nz.net.ultraq.thymeleaf.layoutdialect.LayoutDialect; import nz.net.ultraq.thymeleaf.LayoutDialect;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.thymeleaf.extras.springsecurity6.dialect.SpringSecurityDialect; import org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect;
import org.thymeleaf.spring6.SpringTemplateEngine; import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import org.thymeleaf.templateresolver.ITemplateResolver; import org.thymeleaf.templateresolver.ITemplateResolver;
@ -17,17 +17,30 @@ public class MailTemplateConfiguration {
final SpringTemplateEngine templateEngine = new SpringTemplateEngine(); final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(templateResolver); templateEngine.addTemplateResolver(templateResolver);
templateEngine.addTemplateResolver(emailTemplateResolver()); templateEngine.addTemplateResolver(emailTemplateResolver());
templateEngine.addTemplateResolver(mvcTemplateResolver());
templateEngine.addDialect(new LayoutDialect()); templateEngine.addDialect(new LayoutDialect());
templateEngine.addDialect(sec); templateEngine.addDialect(sec);
return templateEngine; return templateEngine;
} }
private ClassLoaderTemplateResolver emailTemplateResolver() { public ClassLoaderTemplateResolver emailTemplateResolver() {
ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver(); ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver();
emailTemplateResolver.setPrefix("/mail_templates/"); emailTemplateResolver.setPrefix("mail_templates/");
emailTemplateResolver.setTemplateMode("HTML"); emailTemplateResolver.setTemplateMode("HTML5");
emailTemplateResolver.setSuffix(".html"); emailTemplateResolver.setSuffix(".html");
emailTemplateResolver.setOrder(1);
emailTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name()); emailTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
return emailTemplateResolver; return emailTemplateResolver;
} }
public ClassLoaderTemplateResolver mvcTemplateResolver() {
ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver();
emailTemplateResolver.setPrefix("templates");
emailTemplateResolver.setTemplateMode("HTML5");
emailTemplateResolver.setSuffix(".html");
emailTemplateResolver.setOrder(2);
emailTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
return emailTemplateResolver;
}
} }

View File

@ -3,18 +3,16 @@ package ru.ulstu.configuration;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 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.WebMvcConfigurerAdapter;
@Configuration @Configuration
public class MvcConfiguration implements WebMvcConfigurer { public class MvcConfiguration extends WebMvcConfigurerAdapter {
@Override @Override
public void addViewControllers(ViewControllerRegistry registry) { public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/{articlename:\\w+}"); registry.addViewController("/{articlename:\\w+}");
registry.addViewController("/admin/{articlename:\\w+}"); //registry.addViewController("/admin/{articlename:\\w+}");
registry.addViewController("/papers/{articlename:\\w+}"); registry.addViewController("/papers/{articlename:\\w+}");
registry.addViewController("/grants/{articlename:\\w+}"); registry.addViewController("/grants/{articlename:\\w+}");
registry.addViewController("/conferences/{articlename:\\w+}");
registry.addViewController("/students/{articlename:\\w+}");
registry.addRedirectViewController("/", "/index"); registry.addRedirectViewController("/", "/index");
registry.addRedirectViewController("/default", "/index"); registry.addRedirectViewController("/default", "/index");
} }

View File

@ -5,32 +5,27 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import ru.ulstu.core.model.AuthFailureHandler;
import ru.ulstu.user.controller.UserController; import ru.ulstu.user.controller.UserController;
import ru.ulstu.user.model.UserRoleConstants; import ru.ulstu.user.model.UserRoleConstants;
import ru.ulstu.user.service.UserService; import ru.ulstu.user.service.UserService;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration { @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class); private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
@Autowired
private Environment env;
@Value("${server.http.port}") @Value("${server.http.port}")
private int httpPort; private int httpPort;
@Value("${server.port}") @Value("${server.port}")
@ -39,79 +34,82 @@ public class SecurityConfiguration {
private final UserService userService; private final UserService userService;
private final BCryptPasswordEncoder bCryptPasswordEncoder; private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final AuthenticationSuccessHandler authenticationSuccessHandler; private final AuthenticationSuccessHandler authenticationSuccessHandler;
private final AuthenticationFailureHandler authenticationFailureHandler;
private final LogoutSuccessHandler logoutSuccessHandler; private final LogoutSuccessHandler logoutSuccessHandler;
private final ApplicationProperties applicationProperties; private final ApplicationProperties applicationProperties;
private final AuthenticationFailureHandler authenticationFailureHandler;
public SecurityConfiguration(UserService userService, public SecurityConfiguration(UserService userService,
BCryptPasswordEncoder bCryptPasswordEncoder, BCryptPasswordEncoder bCryptPasswordEncoder,
AuthenticationSuccessHandler authenticationSuccessHandler, AuthenticationSuccessHandler authenticationSuccessHandler,
AuthenticationFailureHandler authenticationFailureHandler,
LogoutSuccessHandler logoutSuccessHandler, LogoutSuccessHandler logoutSuccessHandler,
ApplicationProperties applicationProperties, ApplicationProperties applicationProperties) {
AuthFailureHandler authenticationFailureHandler) {
this.userService = userService; this.userService = userService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder; this.bCryptPasswordEncoder = bCryptPasswordEncoder;
this.authenticationSuccessHandler = authenticationSuccessHandler; this.authenticationSuccessHandler = authenticationSuccessHandler;
this.authenticationFailureHandler = authenticationFailureHandler;
this.logoutSuccessHandler = logoutSuccessHandler; this.logoutSuccessHandler = logoutSuccessHandler;
this.applicationProperties = applicationProperties; this.applicationProperties = applicationProperties;
this.authenticationFailureHandler = authenticationFailureHandler;
} }
@Bean @Override
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable); http.csrf()
.disable();
if (applicationProperties.isDevMode()) { if (applicationProperties.isDevMode()) {
log.debug("Security disabled"); log.debug("Security disabled");
http.authorizeHttpRequests((authz) -> authz http.authorizeRequests()
.anyRequest() .anyRequest()
.permitAll() .permitAll();
); http.anonymous()
http.anonymous((anonymousCustomizer) -> anonymousCustomizer .principal("developer")
.principal("admin") .authorities(UserRoleConstants.ADMIN);
.authorities(UserRoleConstants.ADMIN)
);
} else { } else {
log.debug("Security enabled"); log.debug("Security enabled");
http.authorizeHttpRequests((authz) -> authz http.authorizeRequests()
.requestMatchers(UserController.ACTIVATE_URL).permitAll() .antMatchers(UserController.ACTIVATE_URL).permitAll()
.requestMatchers(Constants.PASSWORD_RESET_REQUEST_PAGE).permitAll() .antMatchers(Constants.PASSWORD_RESET_REQUEST_PAGE).permitAll()
.requestMatchers(Constants.PASSWORD_RESET_PAGE).permitAll() .antMatchers(Constants.PASSWORD_RESET_PAGE).permitAll()
.requestMatchers("/users/block").permitAll() .antMatchers(UserController.URL + UserController.REGISTER_URL).permitAll()
.requestMatchers(UserController.URL + UserController.REGISTER_URL).permitAll() .antMatchers(UserController.URL + UserController.ACTIVATE_URL).permitAll()
.requestMatchers(UserController.URL + UserController.ACTIVATE_URL).permitAll() .antMatchers(UserController.URL + UserController.PASSWORD_RESET_REQUEST_URL).permitAll()
.requestMatchers(UserController.URL + UserController.PASSWORD_RESET_REQUEST_URL).permitAll() .antMatchers(UserController.URL + UserController.PASSWORD_RESET_URL).permitAll()
.requestMatchers(UserController.URL + UserController.PASSWORD_RESET_URL).permitAll() .antMatchers("/swagger-ui.html").hasAuthority(UserRoleConstants.ADMIN)
.requestMatchers("/swagger-ui.html").hasAuthority(UserRoleConstants.ADMIN) .anyRequest().authenticated()
.anyRequest().authenticated()) .and()
.formLogin((formLoginCustomizer) -> formLoginCustomizer .formLogin()
.loginPage("/login") .loginPage("/login")
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler) .failureHandler(authenticationFailureHandler)
.successHandler(authenticationSuccessHandler)
.permitAll() .permitAll()
) .and()
.rememberMe(rememberMe -> rememberMe.key("uniqueAndSecret")) .logout()
.logout((logoutCustomizer) -> logoutCustomizer
.logoutSuccessHandler(logoutSuccessHandler) .logoutSuccessHandler(logoutSuccessHandler)
.logoutSuccessUrl(Constants.LOGOUT_URL) .logoutSuccessUrl(Constants.LOGOUT_URL)
.invalidateHttpSession(false) .invalidateHttpSession(false)
.clearAuthentication(true) .clearAuthentication(true)
.deleteCookies(Constants.COOKIES_NAME) .deleteCookies(Constants.COOKIES_NAME)
.permitAll() .permitAll();
);
http.csrf(AbstractHttpConfigurer::disable);
} }
return http.build(); if (applicationProperties.isUseHttps()) {
http.portMapper()
.http(httpPort)
.mapsTo(httpsPort)
.and()
.requiresChannel()
.anyRequest()
.requiresSecure();
} }
@Bean }
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring() @Override
.requestMatchers("/css/**", public void configure(WebSecurity web) {
"/javax.faces.resource/**", web.ignoring()
"/js/**", .antMatchers("/css/**")
"/templates/**", .antMatchers("/js/**")
"/webjars/**", .antMatchers("/templates/**")
"/img/**"); .antMatchers("/webjars/**");
} }
@Autowired @Autowired

View File

@ -0,0 +1,23 @@
package ru.ulstu.configuration;
import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket swaggerApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(Predicates.not(PathSelectors.regex("/error")))
.build();
}
}

View File

@ -4,8 +4,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.validation.FieldError; import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MethodArgumentNotValidException;
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.ModelAttribute; import org.springframework.web.bind.annotation.RestController;
import ru.ulstu.core.error.EntityIdIsNullException; import ru.ulstu.core.error.EntityIdIsNullException;
import ru.ulstu.core.model.ErrorConstants; import ru.ulstu.core.model.ErrorConstants;
import ru.ulstu.core.model.response.Response; import ru.ulstu.core.model.response.Response;
@ -19,25 +20,14 @@ import ru.ulstu.user.error.UserNotActivatedException;
import ru.ulstu.user.error.UserNotFoundException; import ru.ulstu.user.error.UserNotFoundException;
import ru.ulstu.user.error.UserPasswordsNotValidOrNotMatchException; import ru.ulstu.user.error.UserPasswordsNotValidOrNotMatchException;
import ru.ulstu.user.error.UserResetKeyError; import ru.ulstu.user.error.UserResetKeyError;
import ru.ulstu.user.error.UserSendingMailException;
import ru.ulstu.user.service.UserService;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
//@ControllerAdvice @RestController
@ControllerAdvice
public class AdviceController { public class AdviceController {
private final Logger log = LoggerFactory.getLogger(AdviceController.class); private final Logger log = LoggerFactory.getLogger(AdviceController.class);
private final UserService userService;
public AdviceController(UserService userService) {
this.userService = userService;
}
@ModelAttribute("flashMessage")
public String getFlashMessage() {
return null;
}
private Response<Void> handleException(ErrorConstants error) { private Response<Void> handleException(ErrorConstants error) {
log.warn(error.toString()); log.warn(error.toString());
@ -107,9 +97,4 @@ public class AdviceController {
public ResponseExtended<String> handleUserIsUndeadException(Throwable e) { public ResponseExtended<String> handleUserIsUndeadException(Throwable e) {
return handleException(ErrorConstants.USER_UNDEAD_ERROR, e.getMessage()); return handleException(ErrorConstants.USER_UNDEAD_ERROR, e.getMessage());
} }
@ExceptionHandler(UserSendingMailException.class)
public ResponseExtended<String> handleUserSendingMailException(Throwable e) {
return handleException(ErrorConstants.USER_SENDING_MAIL_EXCEPTION, e.getMessage());
}
} }

View File

@ -1,19 +0,0 @@
package ru.ulstu.core.controller;
import org.springframework.validation.Errors;
public class Navigation {
public static final String REDIRECT_TO = "redirect:%s";
public static final String GRANTS_PAGE = "/grants/grants";
public static final String GRANT_PAGE = "/grants/grant";
public static final String CONFERENCES_PAGE = "/conferences/conferences";
public static final String CONFERENCE_PAGE = "/conferences/conference";
public static String hasErrors(Errors errors, String page) {
if (errors.hasErrors()) {
return page;
}
return null;
}
}

View File

@ -0,0 +1,7 @@
package ru.ulstu.core.error;
public class XlsLoadException extends Exception {
public XlsLoadException(String s) {
super(s);
}
}

View File

@ -0,0 +1,7 @@
package ru.ulstu.core.error;
public class XlsParseException extends Exception {
public XlsParseException(String s) {
super(s);
}
}

View File

@ -6,19 +6,19 @@ import org.springframework.data.domain.Sort;
import java.io.Serializable; import java.io.Serializable;
public class OffsetablePageRequest implements Pageable, Serializable { public class OffsetablePageRequest implements Pageable, Serializable {
private final long offset; private final int offset;
private final int count; private final int count;
private final Sort sort; private final Sort sort;
public OffsetablePageRequest(long offset, int count) { public OffsetablePageRequest(int offset, int count) {
this(offset, count, null); this(offset, count, null);
} }
public OffsetablePageRequest(long offset, int count, Sort.Direction direction, String... properties) { public OffsetablePageRequest(int offset, int count, Sort.Direction direction, String... properties) {
this(offset, count, Sort.by(direction, properties)); this(offset, count, new Sort(direction, properties));
} }
public OffsetablePageRequest(long offset, int count, Sort sort) { public OffsetablePageRequest(int offset, int count, Sort sort) {
if (offset < 0) { if (offset < 0) {
throw new IllegalArgumentException("Offset value must not be less than zero!"); throw new IllegalArgumentException("Offset value must not be less than zero!");
} }
@ -30,12 +30,6 @@ public class OffsetablePageRequest implements Pageable, Serializable {
this.sort = sort; this.sort = sort;
} }
@Override
public Pageable withPage(int pageNumber) {
//TODO
return null;
}
@Override @Override
public Sort getSort() { public Sort getSort() {
return sort; return sort;
@ -48,11 +42,11 @@ public class OffsetablePageRequest implements Pageable, Serializable {
@Override @Override
public int getPageNumber() { public int getPageNumber() {
return (int) (offset / count); return offset / count;
} }
@Override @Override
public long getOffset() { public int getOffset() {
return offset; return offset;
} }
@ -71,7 +65,7 @@ public class OffsetablePageRequest implements Pageable, Serializable {
return hasPrevious() ? previous() : first(); return hasPrevious() ? previous() : first();
} }
private Pageable previous() { public Pageable previous() {
return getOffset() == 0 ? this : new OffsetablePageRequest(getOffset() - getPageSize(), getPageSize(), getSort()); return getOffset() == 0 ? this : new OffsetablePageRequest(getOffset() - getPageSize(), getPageSize(), getSort());
} }
@ -95,9 +89,9 @@ public class OffsetablePageRequest implements Pageable, Serializable {
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
long result = 1; int result = 1;
result = prime * result + offset; result = prime * result + offset;
result = prime * result + count; result = prime * result + count;
return (int) result; return result;
} }
} }

View File

@ -1,21 +0,0 @@
package ru.ulstu.core.model;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import ru.ulstu.user.error.UserBlockedException;
import java.io.IOException;
@Component
public class AuthFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException ex) throws IOException {
if (ex.getClass() == UserBlockedException.class) {
response.sendRedirect("/users/block");
}
}
}

View File

@ -1,16 +1,10 @@
package ru.ulstu.core.model; package ru.ulstu.core.model;
import jakarta.persistence.GeneratedValue; import javax.persistence.*;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Version;
import jakarta.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
@MappedSuperclass @MappedSuperclass
public abstract class BaseEntity implements Serializable, Comparable<BaseEntity> { public abstract class BaseEntity implements Serializable, Comparable {
@Id @Id
@GeneratedValue(strategy = GenerationType.TABLE) @GeneratedValue(strategy = GenerationType.TABLE)
private Integer id; private Integer id;
@ -18,6 +12,14 @@ public abstract class BaseEntity implements Serializable, Comparable<BaseEntity>
@Version @Version
private Integer version; private Integer version;
public BaseEntity() {
}
public BaseEntity(Integer id, Integer version) {
this.id = id;
this.version = version;
}
public Integer getId() { public Integer getId() {
return id; return id;
} }
@ -69,8 +71,8 @@ public abstract class BaseEntity implements Serializable, Comparable<BaseEntity>
} }
@Override @Override
public int compareTo(@NotNull BaseEntity o) { public int compareTo(Object o) {
return id != null ? id.compareTo(o.getId()) : -1; return id != null ? id.compareTo(((BaseEntity) o).getId()) : -1;
} }
public void reset() { public void reset() {

View File

@ -6,18 +6,17 @@ public enum ErrorConstants {
VALIDATION_ERROR(2, "Validation error"), VALIDATION_ERROR(2, "Validation error"),
USER_ID_EXISTS(100, "New user can't have id"), USER_ID_EXISTS(100, "New user can't have id"),
USER_ACTIVATION_ERROR(101, "Invalid activation key"), USER_ACTIVATION_ERROR(101, "Invalid activation key"),
USER_EMAIL_EXISTS(102, "Пользователь с таким почтовым ящиком уже существует"), USER_EMAIL_EXISTS(102, "User with same email already exists"),
USER_LOGIN_EXISTS(103, "Пользователь с таким логином уже существует"), USER_LOGIN_EXISTS(103, "User with same login already exists"),
USER_PASSWORDS_NOT_VALID_OR_NOT_MATCH(104, "Пароли введены неверно"), USER_PASSWORDS_NOT_VALID_OR_NOT_MATCH(104, "User passwords is not valid or not match"),
USER_NOT_FOUND(105, "Аккаунт не найден"), USER_NOT_FOUND(105, "User is not found"),
USER_NOT_ACTIVATED(106, "User is not activated"), USER_NOT_ACTIVATED(106, "User is not activated"),
USER_RESET_ERROR(107, "Некорректный ключ подтверждения"), USER_RESET_ERROR(107, "Invalid reset key"),
USER_UNDEAD_ERROR(108, "Can't edit/delete that user"), USER_UNDEAD_ERROR(108, "Can't edit/delete that user"),
FILE_UPLOAD_ERROR(110, "File upload error"), FILE_UPLOAD_ERROR(110, "File upload error");
USER_SENDING_MAIL_EXCEPTION(111, "Во время отправки приглашения пользователю произошла ошибка");
private final int code; private int code;
private final String message; private String message;
ErrorConstants(int code, String message) { ErrorConstants(int code, String message) {
this.code = code; this.code = code;

View File

@ -1,17 +0,0 @@
package ru.ulstu.core.model;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.timeline.model.Event;
import ru.ulstu.user.model.User;
import java.util.List;
public interface EventSource {
List<Deadline> getDeadlines();
String getTitle();
List<User> getRecipients();
void addObjectToEvent(Event event);
}

View File

@ -0,0 +1,34 @@
package ru.ulstu.core.model;
import java.util.ArrayList;
import java.util.List;
public class TreeDto {
private Integer id;
private String text;
private List<TreeDto> children = new ArrayList<>();
public TreeDto() {
}
public <T extends TreeEntity> TreeDto(TreeEntity item) {
this.text = item.toString();
this.id = item.getId();
}
public TreeDto(String rootName) {
this.text = rootName;
}
public String getText() {
return text;
}
public List<TreeDto> getChildren() {
return children;
}
public Integer getId() {
return id;
}
}

View File

@ -0,0 +1,16 @@
package ru.ulstu.core.model;
import java.util.List;
public interface TreeEntity<T> {
Integer getId();
List<T> getChildren();
void setChildren(List<T> children);
T getParent();
void setParent(T parent);
}

View File

@ -1,11 +0,0 @@
package ru.ulstu.core.model;
import ru.ulstu.user.model.User;
import java.util.Set;
public interface UserActivity {
String getTitle();
Set<User> getActivityUsers();
}

View File

@ -0,0 +1,9 @@
package ru.ulstu.core.model;
import ru.ulstu.user.model.User;
import java.util.Set;
public interface UserContainer {
Set<User> getUsers();
}

View File

@ -1,8 +1,8 @@
package ru.ulstu.core.model.response; package ru.ulstu.core.model.response;
class ControllerResponse<D, E> { class ControllerResponse<D, E> {
private final D data; private D data;
private final ControllerResponseError<E> error; private ControllerResponseError<E> error;
ControllerResponse(D data) { ControllerResponse(D data) {
this.data = data; this.data = data;

View File

@ -3,8 +3,8 @@ package ru.ulstu.core.model.response;
import ru.ulstu.core.model.ErrorConstants; import ru.ulstu.core.model.ErrorConstants;
class ControllerResponseError<D> { class ControllerResponseError<D> {
private final ErrorConstants description; private ErrorConstants description;
private final D data; private D data;
ControllerResponseError(ErrorConstants description, D data) { ControllerResponseError(ErrorConstants description, D data) {
this.description = description; this.description = description;

View File

@ -11,6 +11,6 @@ public class Response<D> extends ResponseEntity<Object> {
} }
public Response(ErrorConstants error) { public Response(ErrorConstants error) {
super(new ControllerResponse<Void, Void>(new ControllerResponseError<>(error, null)), HttpStatus.BAD_REQUEST); super(new ControllerResponse<Void, Void>(new ControllerResponseError<>(error, null)), HttpStatus.OK);
} }
} }

View File

@ -7,6 +7,6 @@ import ru.ulstu.core.model.ErrorConstants;
public class ResponseExtended<E> extends ResponseEntity<Object> { public class ResponseExtended<E> extends ResponseEntity<Object> {
public ResponseExtended(ErrorConstants error, E errorData) { public ResponseExtended(ErrorConstants error, E errorData) {
super(new ControllerResponse<Void, E>(new ControllerResponseError<E>(error, errorData)), HttpStatus.BAD_REQUEST); super(new ControllerResponse<Void, E>(new ControllerResponseError<E>(error, errorData)), HttpStatus.OK);
} }
} }

View File

@ -1,69 +0,0 @@
package ru.ulstu.core.navigation;
public class Page {
public static final String INDEX = "/index.html";
public static final String PAPER = "/paper/paper.html";
public static final String PAPER_LIST = "/paper/papers.html";
public static final String PAPER_DASHBOARD = "/paper/dashboard.html";
public static final String GRANT = "/grant/grant.html";
public static final String GRANT_LIST = "/grant/grants.html";
public static final String GRANT_DASHBOARD = "/grant/dashboard.html";
public static final String USER_LIST = "/admin/users.html";
public static final String LOGOUT = "/logout";
public static final String CONFERENCE = "/conference/conference.html";
public static final String CONFERENCE_DASHBOARD = "/conference/dashboard.html";
public static final String CONFERENCE_LIST = "/conference/conferences.html";
public static final String PROJECT_DASHBOARD = "/conference/dashboard.html";
public String getIndex() {
return INDEX;
}
public String getPaperList() {
return PAPER_LIST;
}
public String getPaperDashboard() {
return PAPER_DASHBOARD;
}
public String getUserList() {
return USER_LIST;
}
public String getLogout() {
return LOGOUT;
}
public String getGrantList() {
return GRANT_LIST;
}
public String getGrantDashboard() {
return GRANT_DASHBOARD;
}
public String getPaper() {
return PAPER;
}
public String getGrant() {
return GRANT;
}
public String getConferenceDashboard() {
return CONFERENCE_DASHBOARD;
}
public String getProjectDashboard() {
return PROJECT_DASHBOARD;
}
public String getConference() {
return CONFERENCE;
}
public String getConferenceList() {
return CONFERENCE_LIST;
}
}

View File

@ -1,14 +1,14 @@
package ru.ulstu.core.repository; package ru.ulstu.core.repository;
import jakarta.persistence.EntityManager;
import org.springframework.data.jpa.repository.support.JpaEntityInformation; import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository; import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import javax.persistence.EntityManager;
import java.io.Serializable; import java.io.Serializable;
public class JpaDetachableRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> public class JpaDetachableRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
implements JpaDetachableRepository<T, ID> { implements JpaDetachableRepository<T, ID> {
private final EntityManager entityManager; private EntityManager entityManager;
public JpaDetachableRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) { public JpaDetachableRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager); super(entityInformation, entityManager);

View File

@ -0,0 +1,31 @@
package ru.ulstu.core.service;
import org.springframework.stereotype.Service;
import ru.ulstu.core.model.TreeDto;
import ru.ulstu.core.model.TreeEntity;
import java.util.List;
import java.util.function.Predicate;
@Service
public class TreeService<T extends TreeEntity> {
public TreeDto getTree(String rootName, List<T> rootItems) {
return addChildNode(new TreeDto(rootName), rootItems, element -> true);
}
public TreeDto getTree(String rootName, List<T> rootItems, Predicate<T> filterPredicate) {
return addChildNode(new TreeDto(rootName), rootItems, filterPredicate);
}
private TreeDto addChildNode(TreeDto currentRoot, List<T> children, Predicate<T> filterPredicate) {
if (children != null) {
children.stream()
.filter(filterPredicate)
.forEach(item -> {
TreeDto newNode = new TreeDto(item);
currentRoot.getChildren().add(addChildNode(newNode, item.getChildren(), filterPredicate));
});
}
return currentRoot;
}
}

View File

@ -0,0 +1,207 @@
package ru.ulstu.core.service;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import ru.ulstu.core.error.XlsParseException;
import java.io.*;
public class XlsDocumentBuilder {
private static final int DEFAULT_SHEET_NUM = 0;
private File documentFile;
private Workbook workBook;
private Sheet currentSheet;
/**
* Constructor for reading and writing data from/to *.[xls|xlsx] document
*
* @param file contains existing document for reading or new document to save
*/
public XlsDocumentBuilder(File file) throws IOException, XlsParseException {
this.documentFile = file;
if (file.exists()) {
workBook = getWorkBook(file);
currentSheet = workBook.getSheetAt(DEFAULT_SHEET_NUM);
} else {
workBook = new XSSFWorkbook();
currentSheet = workBook.createSheet();
}
}
private Workbook getWorkBook(File file) throws XlsParseException, IOException {
InputStream inputStream = new PushbackInputStream(new FileInputStream(file), 4096);
if (isXlsx(inputStream)) {
return new XSSFWorkbook(inputStream);
} else if (isExcel(inputStream)) {
return new HSSFWorkbook(inputStream);
}
throw new XlsParseException("Wrong document format");
}
/**
* Change active sheet to write or read data
*
* @param index index of sheet to activate
*/
public XlsDocumentBuilder setActiveSheet(int index) {
workBook.setActiveSheet(index);
currentSheet = workBook.getSheetAt(index);
return this;
}
/**
* Create new sheet in document and set it active
*
* @param sheetName
*/
public XlsDocumentBuilder insertNewSheet(String sheetName) {
currentSheet = workBook.createSheet(sheetName);
workBook.setActiveSheet(getSheetCount() - 1);
return this;
}
public XlsDocumentBuilder insertNewSheet(String sheetName, int order) {
insertNewSheet(sheetName);
workBook.setSheetOrder(sheetName, order);
return this;
}
/**
* Returns number of sheet in document
*
* @return sheets count
*/
public int getSheetCount() {
return workBook.getNumberOfSheets();
}
/**
* Returns number of rows in sheet
*
* @return rows count
*/
public int getRowCount() {
return currentSheet.getLastRowNum();
}
/**
* Returns number of columns in sheet
*
* @return columns count
*/
public int getColumnCount() {
Row row = currentSheet.getRow(getRowCount());
if (row == null) {
return 0;
}
return row.getLastCellNum() - 1;
}
/**
* Returns converted to string representation of cell value
*
* @param rowIndex row index of current sheet
* @param colIndex column index of current sheet
* @return string value of cell
*/
public String getCellAsString(int rowIndex, int colIndex) {
Cell cell = currentSheet.getRow(rowIndex).getCell(colIndex);
cell.setCellType(Cell.CELL_TYPE_STRING);
return cell.getStringCellValue();
}
/**
* Sets string cell value
*
* @param rowIndex row index of current sheet
* @param colIndex column index of current sheet
*/
public XlsDocumentBuilder setCellValue(int rowIndex, int colIndex, String value) {
if (currentSheet.getRow(rowIndex) == null) {
currentSheet.createRow(rowIndex);
}
if (currentSheet.getRow(rowIndex).getCell(colIndex) == null) {
currentSheet.getRow(rowIndex).createCell(colIndex);
}
Cell cell = currentSheet.getRow(rowIndex).getCell(colIndex);
cell.setCellValue(value);
setColumnAutosize(colIndex, colIndex);
return this;
}
public XlsDocumentBuilder setCellValue(int rowIndex, int colIndex, int value) {
return setCellValue(rowIndex, colIndex, String.valueOf(value));
}
public XlsDocumentBuilder setCellValue(int rowIndex, int colIndex, long value) {
return setCellValue(rowIndex, colIndex, String.valueOf(value));
}
/**
* Save current file
*/
public XlsDocumentBuilder save() throws IOException {
OutputStream out = new FileOutputStream(documentFile);
workBook.write(out);
return this;
}
private boolean isExcel(InputStream i) throws IOException {
return (POIFSFileSystem.hasPOIFSHeader(i) || POIXMLDocument.hasOOXMLHeader(i));
}
private boolean isXlsx(InputStream i) throws IOException {
return POIXMLDocument.hasOOXMLHeader(i);
}
public int getActiveSheetIndex() {
return workBook.getActiveSheetIndex();
}
public XlsDocumentBuilder mergeCells(int rowFrom, int rowTo, int colFrom, int colTo) {
currentSheet.addMergedRegion(new CellRangeAddress(rowFrom, rowTo, colFrom, colTo));
return this;
}
public void setRegionBorderWithMedium(int rowFrom, int rowTo, int colFrom, int colTo) {
for (int row = rowFrom; row < rowTo; row++) {
for (int col = colFrom; col <= colTo; col++) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(row, row, col, col);
RegionUtil.setBorderBottom(CellStyle.BORDER_THIN, cellRangeAddress, currentSheet, workBook);
RegionUtil.setBorderLeft(CellStyle.BORDER_THIN, cellRangeAddress, currentSheet, workBook);
RegionUtil.setBorderRight(CellStyle.BORDER_THIN, cellRangeAddress, currentSheet, workBook);
RegionUtil.setBorderTop(CellStyle.BORDER_THIN, cellRangeAddress, currentSheet, workBook);
}
}
}
public XlsDocumentBuilder setColumnAutosize(int from, int to) {
for (int col = from; col <= to; col++) {
currentSheet.autoSizeColumn(col, true);
}
return this;
}
public XlsDocumentBuilder setRowAutosize(int from, int to) {
CellStyle style = workBook.createCellStyle();
style.setWrapText(true);
for (int row = from; row <= to; row++) {
for (int col = 0; col <= currentSheet.getRow(row).getLastCellNum(); col++) {
if (currentSheet.getRow(row).getCell(col) != null) {
currentSheet.getRow(row).getCell(col).setCellStyle(style);
}
}
}
return this;
}
public XlsDocumentBuilder deleteSheet(int index) {
workBook.removeSheetAt(index);
return this;
}
}

View File

@ -1,11 +1,6 @@
package ru.ulstu.core.util; package ru.ulstu.core.util;
import java.time.Instant; import java.time.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
@ -14,12 +9,9 @@ import java.util.List;
public class DateUtils { public class DateUtils {
public static Date clearTime(Date date) { public static Date clearTime(Date date) {
if (date == null) {
return null;
}
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTime(date); calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.MILLISECOND, 0);
@ -57,16 +49,4 @@ public class DateUtils {
cal.add(Calendar.DAY_OF_MONTH, count); cal.add(Calendar.DAY_OF_MONTH, count);
return cal.getTime(); return cal.getTime();
} }
public static Date addYears(Date date, int count) {
Calendar cal = getCalendar(date);
cal.add(Calendar.YEAR, count);
return cal.getTime();
}
public static LocalDate convertToLocalDate(Date dateToConvert) {
return dateToConvert.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
}
} }

View File

@ -0,0 +1,17 @@
package ru.ulstu.core.util;
public class NumberUtils {
public static Double ceil(Double number) {
if (number == null) {
return 0.0;
}
return Double.valueOf(Math.ceil(number));
}
public static Double round(Double number) {
if (number == null) {
return 0.0;
}
return Double.valueOf(Math.ceil(number * 100)) / 100;
}
}

View File

@ -11,12 +11,12 @@ public class StreamApiUtils {
public static <T, R> List<T> convert(List<R> entities, Function<R, T> converter) { public static <T, R> List<T> convert(List<R> entities, Function<R, T> converter) {
return entities == null return entities == null
? Collections.emptyList() ? Collections.emptyList()
: entities.stream().map(converter).collect(Collectors.toList()); : entities.stream().map(e -> converter.apply(e)).collect(Collectors.toList());
} }
public static <T, R> Set<T> convert(Set<R> entities, Function<R, T> converter) { public static <T, R> Set<T> convert(Set<R> entities, Function<R, T> converter) {
return entities == null return entities == null
? Collections.emptySet() ? Collections.emptySet()
: entities.stream().map(converter).collect(Collectors.toSet()); : entities.stream().map(e -> converter.apply(e)).collect(Collectors.toSet());
} }
} }

View File

@ -1,34 +1,20 @@
package ru.ulstu.deadline.model; package ru.ulstu.deadline.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import org.springframework.format.annotation.DateTimeFormat;
import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.user.model.User;
import javax.persistence.Entity;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Objects;
@Entity @Entity
public class Deadline extends BaseEntity { public class Deadline extends BaseEntity {
private String description; private String description;
@Temporal(value = TemporalType.DATE) @Temporal(value = TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date date; private Date date;
@OneToMany(targetEntity = User.class, fetch = FetchType.EAGER)
private List<User> executors;
private Boolean done;
public Deadline() { public Deadline() {
} }
@ -37,26 +23,6 @@ public class Deadline extends BaseEntity {
this.description = description; this.description = description;
} }
public Deadline(Date deadlineDate, String description, List<User> executors, Boolean done) {
this.date = deadlineDate;
this.description = description;
this.executors = executors;
this.done = done;
}
@JsonCreator
public Deadline(@JsonProperty("id") Integer id,
@JsonProperty("description") String description,
@JsonProperty("date") Date date,
@JsonProperty("executors") List<User> executors,
@JsonProperty("done") Boolean done) {
this.setId(id);
this.description = description;
this.date = date;
this.executors = executors;
this.done = done;
}
public String getDescription() { public String getDescription() {
return description; return description;
} }
@ -72,47 +38,4 @@ public class Deadline extends BaseEntity {
public void setDate(Date date) { public void setDate(Date date) {
this.date = date; this.date = date;
} }
public List<User> getExecutors() {
return executors;
}
public void setExecutors(List<User> executors) {
this.executors = executors;
}
public Boolean getDone() {
return done;
}
public void setDone(Boolean done) {
this.done = done;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
Deadline deadline = (Deadline) o;
if (getId() == null && deadline.getId() == null &&
description == null && deadline.description == null &&
date == null && deadline.date == null) {
return true;
}
return getId().equals(deadline.getId()) &&
description.equals(deadline.description) &&
date.equals(deadline.date);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), description, date, executors, done);
}
} }

View File

@ -0,0 +1,58 @@
package ru.ulstu.deadline.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
public class DeadlineDto {
private Integer id;
private String description;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date date;
public DeadlineDto() {
}
@JsonCreator
public DeadlineDto(@JsonProperty("id") Integer id,
@JsonProperty("description") String description,
@JsonProperty("date") Date date) {
this.id = id;
this.description = description;
this.date = date;
}
public DeadlineDto(Deadline deadline) {
this.id = deadline.getId();
this.description = deadline.getDescription();
this.date = deadline.getDate();
}
public Integer getId() {
return id;
}
public String getDescription() {
return description;
}
public Date getDate() {
return date;
}
public void setId(Integer id) {
this.id = id;
}
public void setDescription(String description) {
this.description = description;
}
public void setDate(Date date) {
this.date = date;
}
}

View File

@ -2,14 +2,8 @@ package ru.ulstu.deadline.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.repository.query.Param;
import ru.ulstu.deadline.model.Deadline; import ru.ulstu.deadline.model.Deadline;
import java.util.Date;
public interface DeadlineRepository extends JpaRepository<Deadline, Integer> { public interface DeadlineRepository extends JpaRepository<Deadline, Integer> {
@Query("SELECT d.date FROM Grant g JOIN g.deadlines d WHERE (g.id = :id) AND (d.date = :date)")
Date findByGrantIdAndDate(@Param("id") Integer grantId, @Param("date") Date date);
} }

View File

@ -2,12 +2,10 @@ package ru.ulstu.deadline.service;
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.core.util.DateUtils;
import ru.ulstu.deadline.model.Deadline; import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.deadline.model.DeadlineDto;
import ru.ulstu.deadline.repository.DeadlineRepository; import ru.ulstu.deadline.repository.DeadlineRepository;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -19,63 +17,29 @@ public class DeadlineService {
this.deadlineRepository = deadlineRepository; this.deadlineRepository = deadlineRepository;
} }
public List<Deadline> saveOrCreate(List<Deadline> deadlines) { public List<Deadline> saveOrCreate(List<DeadlineDto> deadlines) {
return deadlines return deadlines.stream().map(deadlineDto -> {
.stream() return deadlineDto.getId() != null ? update(deadlineDto) : create(deadlineDto);
.map(deadline -> {
return deadline.getId() != null ? update(deadline) : create(deadline);
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
@Transactional @Transactional
private Deadline update(Deadline deadline) { public Deadline update(DeadlineDto deadlineDto) {
Deadline updateDeadline = deadlineRepository.getOne(deadline.getId()); Deadline deadline = deadlineRepository.findOne(deadlineDto.getId());
updateDeadline.setDate(deadline.getDate()); deadlineRepository.save(copyFromDto(deadline, deadlineDto));
updateDeadline.setDescription(deadline.getDescription()); return deadline;
updateDeadline.setExecutors(deadline.getExecutors());
updateDeadline.setDone(deadline.getDone());
deadlineRepository.save(updateDeadline);
return updateDeadline;
} }
@Transactional @Transactional
public Deadline create(Deadline deadline) { public Deadline create(DeadlineDto deadlineDto) {
Deadline newDeadline = new Deadline(); Deadline newDeadline = copyFromDto(new Deadline(), deadlineDto);
newDeadline.setDate(deadline.getDate());
newDeadline.setDescription(deadline.getDescription());
newDeadline.setExecutors(deadline.getExecutors());
newDeadline.setDone(deadline.getDone());
newDeadline = deadlineRepository.save(newDeadline); newDeadline = deadlineRepository.save(newDeadline);
return newDeadline; return newDeadline;
} }
public Deadline create(Date date) { private Deadline copyFromDto(Deadline deadline, DeadlineDto deadlineDto) {
Deadline deadline = new Deadline(); deadline.setDate(deadlineDto.getDate());
deadline.setDate(date); deadline.setDescription(deadlineDto.getDescription());
return create(deadline); return deadline;
}
public Deadline create(String description, Date date) {
Deadline deadline = new Deadline();
deadline.setDate(date);
deadline.setDescription(description);
return create(deadline);
}
@Transactional
public void remove(Integer deadlineId) {
deadlineRepository.deleteById(deadlineId);
}
public Date findByGrantIdAndDate(Integer id, Date date) {
return deadlineRepository.findByGrantIdAndDate(id, date);
}
public Deadline createWithOffset(Date date, long value, ChronoUnit chronoUnit) {
return create(DateUtils.localDateToDate(DateUtils.convertToLocalDate(date).plus(value, chronoUnit)));
}
public void delete(List<Deadline> deadlines) {
deadlineRepository.deleteInBatch(deadlines);
} }
} }

View File

@ -13,7 +13,6 @@ import org.springframework.web.multipart.MultipartFile;
import ru.ulstu.configuration.Constants; import ru.ulstu.configuration.Constants;
import ru.ulstu.core.model.response.Response; import ru.ulstu.core.model.response.Response;
import ru.ulstu.file.model.FileData; import ru.ulstu.file.model.FileData;
import ru.ulstu.file.model.FileDataDto;
import ru.ulstu.file.service.FileService; import ru.ulstu.file.service.FileService;
import java.io.IOException; import java.io.IOException;
@ -21,10 +20,13 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static ru.ulstu.file.FileController.URL;
@RestController @RestController
@RequestMapping(Constants.API_1_0 + "files") @RequestMapping(URL)
public class FileController { public class FileController {
public static final String URL = Constants.API_1_0 + "files";
private final FileService fileService; private final FileService fileService;
public FileController(FileService fileService) { public FileController(FileService fileService) {
@ -49,7 +51,7 @@ public class FileController {
} }
@PostMapping("/uploadTmpFile") @PostMapping("/uploadTmpFile")
public Response<FileDataDto> upload(@RequestParam("file") MultipartFile multipartFile) throws IOException { public Response<String> upload(@RequestParam("file") MultipartFile multipartFile) throws IOException {
return new Response<>(fileService.createFromMultipartFile(multipartFile)); return new Response(fileService.uploadToTmpDir(multipartFile));
} }
} }

View File

@ -1,10 +1,10 @@
package ru.ulstu.file.model; package ru.ulstu.file.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.BaseEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.Date; import java.util.Date;
@Entity @Entity
@ -19,9 +19,6 @@ public class FileData extends BaseEntity {
private byte[] data; private byte[] data;
@Column(name = "is_latex_attach")
private Boolean isLatexAttach;
public String getName() { public String getName() {
return name; return name;
} }
@ -53,12 +50,4 @@ public class FileData extends BaseEntity {
public void setData(byte[] data) { public void setData(byte[] data) {
this.data = data; this.data = data;
} }
public Boolean isLatexAttach() {
return isLatexAttach;
}
public void setLatexAttach(Boolean latexAttach) {
isLatexAttach = latexAttach;
}
} }

View File

@ -1,95 +0,0 @@
package ru.ulstu.file.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class FileDataDto {
private Integer id;
private String name;
private String fileName;
private String tmpFileName;
private boolean deleted;
private Boolean isLatexAttach;
public FileDataDto() {
}
@JsonCreator
public FileDataDto(@JsonProperty("id") Integer id,
@JsonProperty("name") String name,
@JsonProperty("isLatexAttach") Boolean isLatexAttach,
@JsonProperty("fileName") String fileName,
@JsonProperty("tmpFileName") String tmpFileName) {
this.id = id;
this.name = name;
this.fileName = fileName;
this.tmpFileName = tmpFileName;
this.isLatexAttach = isLatexAttach;
}
public FileDataDto(FileData fileData) {
this.id = fileData.getId();
this.name = fileData.getName();
this.isLatexAttach = fileData.isLatexAttach();
}
public FileDataDto(String fileName, String tmpFileName) {
this.fileName = fileName;
this.tmpFileName = tmpFileName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getTmpFileName() {
return tmpFileName;
}
public void setTmpFileName(String tmpFileName) {
this.tmpFileName = tmpFileName;
}
public boolean isDeleted() {
return deleted;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public Boolean isLatexAttach() {
return isLatexAttach;
}
public Boolean getIsLatexAttach() {
return isLatexAttach;
}
public void setLatexAttach(Boolean latexAttach) {
isLatexAttach = latexAttach;
}
public void setIsLatexAttach(Boolean latexAttach) {
isLatexAttach = latexAttach;
}
}

View File

@ -1,24 +1,15 @@
package ru.ulstu.file.service; package ru.ulstu.file.service;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import ru.ulstu.file.model.FileData; import ru.ulstu.file.model.FileData;
import ru.ulstu.file.model.FileDataDto;
import ru.ulstu.file.repostory.FileRepository; import ru.ulstu.file.repostory.FileRepository;
import ru.ulstu.paper.model.PaperDto;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
@ -27,24 +18,24 @@ public class FileService {
private final static int META_FILE_NAME_INDEX = 0; private final static int META_FILE_NAME_INDEX = 0;
private final static int META_FILE_SIZE_INDEX = 1; private final static int META_FILE_SIZE_INDEX = 1;
private final String tmpDir; private String tmpDir;
private final FileRepository fileRepository; private FileRepository fileRepository;
public FileService(FileRepository fileRepository) { public FileService(FileRepository fileRepository) {
tmpDir = System.getProperty("java.io.tmpdir"); tmpDir = System.getProperty("java.io.tmpdir");
this.fileRepository = fileRepository; this.fileRepository = fileRepository;
} }
private FileData createFileFromTmp(String tmpFileName) throws IOException { public FileData createFileFromTmp(String tmpFileName) throws IOException {
FileData fileData = new FileData(); FileData fileData = new FileData();
fileData.setData(getTmpFile(tmpFileName)); fileData.setData(getTmpFile(tmpFileName));
fileData.setSize(getTmpFileSize(tmpFileName)); fileData.setName(getTmpFileName(tmpFileName));
fileData.setCreateDate(new Date()); fileData.setCreateDate(new Date());
return fileRepository.save(fileData); return fileRepository.save(fileData);
} }
private String uploadToTmpDir(MultipartFile multipartFile) throws IOException { public String uploadToTmpDir(MultipartFile multipartFile) throws IOException {
String tmpFileName = String.valueOf(System.currentTimeMillis()) + UUID.randomUUID(); String tmpFileName = String.valueOf(System.currentTimeMillis());
Files.write(getTmpFilePath(tmpFileName), multipartFile.getBytes()); Files.write(getTmpFilePath(tmpFileName), multipartFile.getBytes());
String meta = multipartFile.getOriginalFilename() + "\n" + multipartFile.getSize(); String meta = multipartFile.getOriginalFilename() + "\n" + multipartFile.getSize();
Files.write(getTmpFileMetaPath(tmpFileName), meta.getBytes(UTF_8)); Files.write(getTmpFileMetaPath(tmpFileName), meta.getBytes(UTF_8));
@ -56,7 +47,7 @@ public class FileService {
.split("\n"); .split("\n");
} }
private long getTmpFileSize(String tmpFileName) throws IOException { public long getTmpFileSize(String tmpFileName) throws IOException {
return Long.valueOf(getMeta(tmpFileName)[META_FILE_SIZE_INDEX]).longValue(); return Long.valueOf(getMeta(tmpFileName)[META_FILE_SIZE_INDEX]).longValue();
} }
@ -69,7 +60,7 @@ public class FileService {
} }
public FileData getFile(Integer fileId) { public FileData getFile(Integer fileId) {
return fileRepository.getOne(fileId); return fileRepository.findOne(fileId);
} }
public void deleteTmpFile(String tmpFileName) throws IOException { public void deleteTmpFile(String tmpFileName) throws IOException {
@ -87,63 +78,4 @@ public class FileService {
public void deleteFile(FileData fileData) { public void deleteFile(FileData fileData) {
fileRepository.delete(fileData); fileRepository.delete(fileData);
} }
public List<FileData> saveOrCreate(List<FileDataDto> fileDtos) throws IOException {
List<FileData> files = new ArrayList<>();
for (FileDataDto file : fileDtos) {
files.add(file.getId() != null ? update(file) : create(file));
}
return files;
}
@Transactional
private FileData update(FileDataDto fileDataDto) {
FileData file = fileRepository.getOne(fileDataDto.getId());
return fileRepository.save(copyFromDto(file, fileDataDto));
}
@Transactional
private FileData create(FileDataDto fileDataDto) throws IOException {
FileData newFile = createFileFromTmp(fileDataDto.getTmpFileName());
copyFromDto(newFile, fileDataDto);
return fileRepository.save(newFile);
}
private FileData copyFromDto(FileData fileData, FileDataDto fileDataDto) {
fileData.setName(fileDataDto.getName());
fileData.setLatexAttach(fileDataDto.isLatexAttach());
return fileData;
}
@Transactional
public void delete(Integer fileId) {
fileRepository.delete(fileRepository.getOne(fileId));
}
public FileDataDto createFromMultipartFile(MultipartFile multipartFile) throws IOException {
return new FileDataDto(multipartFile.getOriginalFilename(), uploadToTmpDir(multipartFile));
}
public void createLatexAttachs(PaperDto paper) throws IOException {
for (FileDataDto fileDataDto : paper.getFiles()
.stream()
.filter(f -> (f.isLatexAttach() != null && f.isLatexAttach()) && !f.isDeleted())
.collect(Collectors.toList())) {
if (fileDataDto.getId() == null) {
File oldFile = getTmpFilePath(fileDataDto.getTmpFileName()).toFile();
File renamed = getTmpFilePath(fileDataDto.getName()).toFile();
oldFile.renameTo(renamed);
} else {
Files.write(getTmpFilePath(fileDataDto.getName()), fileRepository.getOne(fileDataDto.getId()).getData());
}
}
}
public File createLatexFile(PaperDto paper) throws IOException {
BufferedWriter writer = Files.newBufferedWriter(getTmpFilePath(paper.getTitle() + ".tex"));
writer.write(paper.getLatexText());
writer.close();
return getTmpFilePath(paper.getTitle() + ".tex").toFile();
}
} }

View File

@ -1,7 +1,5 @@
package ru.ulstu.grant.controller; package ru.ulstu.grant.controller;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors; import org.springframework.validation.Errors;
@ -11,25 +9,21 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
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.ResponseBody; import ru.ulstu.deadline.model.DeadlineDto;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.grant.model.Grant; import ru.ulstu.grant.model.Grant;
import ru.ulstu.grant.model.GrantDto; import ru.ulstu.grant.model.GrantDto;
import ru.ulstu.grant.service.GrantService; import ru.ulstu.grant.service.GrantService;
import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.user.model.User;
import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import static ru.ulstu.core.controller.Navigation.GRANTS_PAGE; import static org.springframework.util.StringUtils.isEmpty;
import static ru.ulstu.core.controller.Navigation.GRANT_PAGE;
import static ru.ulstu.core.controller.Navigation.REDIRECT_TO;
@Controller() @Controller()
@RequestMapping(value = "/grants") @RequestMapping(value = "/grants")
@Hidden
public class GrantController { public class GrantController {
private final GrantService grantService; private final GrantService grantService;
@ -44,70 +38,54 @@ public class GrantController {
@GetMapping("/dashboard") @GetMapping("/dashboard")
public void getDashboard(ModelMap modelMap) { public void getDashboard(ModelMap modelMap) {
modelMap.put("grants", grantService.findAllActiveDto()); modelMap.put("grants", grantService.findAllDto());
} }
@GetMapping("/grant") @GetMapping("/grant")
public void getGrant(ModelMap modelMap, @RequestParam(value = "id") Integer id) { public void getGrant(ModelMap modelMap, @RequestParam(value = "id") Integer id) {
if (id != null && id > 0) { if (id != null && id > 0) {
GrantDto grantDto = grantService.getExistGrantById(id); modelMap.put("grantDto", grantService.findOneDto(id));
attachPaper(grantDto);
modelMap.put("grantDto", grantDto);
} else { } else {
modelMap.put("grantDto", new GrantDto()); modelMap.put("grantDto", new GrantDto());
} }
} }
@PostMapping(value = "/grant", params = "save") @PostMapping(value = "/grant", params = "save")
public String save(@Valid GrantDto grantDto, Errors errors) public String save(@Valid GrantDto grantDto, Errors errors) throws IOException {
throws IOException { filterEmptyDeadlines(grantDto);
if (!grantService.save(grantDto, errors)) { if (grantDto.getDeadlines().isEmpty()) {
return GRANT_PAGE; errors.rejectValue("deadlines", "errorCode", "Не может быть пустым");
} }
return String.format(REDIRECT_TO, GRANTS_PAGE); if (errors.hasErrors()) {
return "/grants/grant";
} }
grantService.save(grantDto);
@PostMapping(value = "/grant", params = "filterUsers") return "redirect:/grants/grants";
public String filterUsers() {
return GRANT_PAGE;
}
@PostMapping(value = "/grant", params = "attachPaper")
public String attachPaper(GrantDto grantDto) {
grantService.attachPaper(grantDto);
return GRANT_PAGE;
} }
@PostMapping(value = "/grant", params = "addDeadline") @PostMapping(value = "/grant", params = "addDeadline")
public String addDeadline(@Valid GrantDto grantDto, Errors errors) { public String addDeadline(@Valid GrantDto grantDto, Errors errors) {
grantService.filterEmptyDeadlines(grantDto); filterEmptyDeadlines(grantDto);
if (errors.hasErrors()) { if (errors.hasErrors()) {
return GRANT_PAGE; return "/grants/grant";
} }
grantDto.getDeadlines().add(new Deadline()); grantDto.getDeadlines().add(new DeadlineDto());
return GRANT_PAGE; return "/grants/grant";
}
@PostMapping(value = "/grant", params = "removeDeadline")
public String removeDeadline(GrantDto grantDto,
@RequestParam(value = "removeDeadline") Integer deadlineId) {
grantService.removeDeadline(grantDto, deadlineId);
return GRANT_PAGE;
} }
@PostMapping(value = "/grant", params = "createProject") @PostMapping(value = "/grant", params = "createProject")
public String createProject(@Valid GrantDto grantDto, Errors errors) throws IOException { public String createProject(@Valid GrantDto grantDto, Errors errors) {
if (errors.hasErrors()) { if (errors.hasErrors()) {
return GRANT_PAGE; return "/grants/grant";
} }
grantService.createProject(grantDto); grantService.createProject(grantDto);
return GRANT_PAGE; return "/grants/grant";
} }
@GetMapping("/delete/{grant-id}") @GetMapping("/delete/{grant-id}")
public String delete(@PathVariable("grant-id") Integer grantId) throws IOException { public String delete(@PathVariable("grant-id") Integer grantId) throws IOException {
grantService.delete(grantId); grantService.delete(grantId);
return String.format(REDIRECT_TO, GRANTS_PAGE); return "redirect:/grants/grants";
} }
@ModelAttribute("allStatuses") @ModelAttribute("allStatuses")
@ -115,19 +93,9 @@ public class GrantController {
return grantService.getGrantStatuses(); return grantService.getGrantStatuses();
} }
@ModelAttribute("allAuthors") private void filterEmptyDeadlines(GrantDto grantDto) {
public List<User> getAllAuthors(GrantDto grantDto) { grantDto.setDeadlines(grantDto.getDeadlines().stream()
return grantService.getGrantAuthors(grantDto); .filter(dto -> dto.getDate() != null || !isEmpty(dto.getDescription()))
} .collect(Collectors.toList()));
@ModelAttribute("allPapers")
public List<PaperDto> getAllPapers() {
return grantService.getAllUncompletedPapers();
}
@ResponseBody
@PostMapping(value = "/ping")
public void ping(@RequestParam("grantId") int grantId) throws IOException {
grantService.ping(grantId);
} }
} }

View File

@ -1,29 +0,0 @@
package ru.ulstu.grant.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.ulstu.configuration.Constants;
import ru.ulstu.grant.service.GrantService;
import java.io.IOException;
import java.text.ParseException;
import static ru.ulstu.paper.controller.PaperRestController.URL;
@RestController
@RequestMapping(URL)
public class GrantRestController {
public static final String URL = Constants.API_1_0 + "grants";
private final GrantService grantService;
public GrantRestController(GrantService grantService) {
this.grantService = grantService;
}
@GetMapping("/grab")
public void grab() throws IOException, ParseException {
grantService.createFromKias();
}
}

View File

@ -1,70 +1,46 @@
package ru.ulstu.grant.model; package ru.ulstu.grant.model;
import jakarta.persistence.CascadeType; import org.hibernate.validator.constraints.NotBlank;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderBy;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.core.model.EventSource;
import ru.ulstu.core.model.UserActivity;
import ru.ulstu.deadline.model.Deadline; import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.file.model.FileData; import ru.ulstu.file.model.FileData;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.project.model.Project; import ru.ulstu.project.model.Project;
import ru.ulstu.timeline.model.Event;
import ru.ulstu.user.model.User;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
@Entity @Entity
@Table(name = "grants") @Table(name = "grants")
@DiscriminatorValue("GRANT") public class Grant extends BaseEntity {
public class Grant extends BaseEntity implements UserActivity, EventSource {
public enum GrantStatus { public enum GrantStatus {
APPLICATION("Заявка", "text-draft"), APPLICATION("Заявка"),
ON_COMPETITION("Отправлен на конкурс", "text-review"), ON_COMPETITION("Отправлен на конкурс"),
SUCCESSFUL_PASSAGE("Успешное прохождение", "text-accepted"), SUCCESSFUL_PASSAGE("Успешное прохождение"),
IN_WORK("В работе", "text-primary"), IN_WORK("В работе"),
COMPLETED("Завершен", "text-success"), COMPLETED("Завершен"),
FAILED("Провалены сроки", "text-failed"), FAILED("Провалены сроки");
LOADED_FROM_KIAS("Загружен автоматически", "text-warning"),
SKIPPED("Не интересует", "text-not-accepted");
private final String statusName; private String statusName;
private final String elementClass;
GrantStatus(String statusName, String elementClass) { GrantStatus(String statusName) {
this.statusName = statusName; this.statusName = statusName;
this.elementClass = elementClass;
} }
public String getStatusName() { public String getStatusName() {
return statusName; return statusName;
} }
public String getElementClass() {
return elementClass;
}
} }
@NotBlank @NotBlank
@ -73,41 +49,23 @@ public class Grant extends BaseEntity implements UserActivity, EventSource {
@Enumerated(value = EnumType.STRING) @Enumerated(value = EnumType.STRING)
private GrantStatus status = GrantStatus.APPLICATION; private GrantStatus status = GrantStatus.APPLICATION;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "grant_id") @JoinColumn(name = "grant_id")
@OrderBy("date")
private List<Deadline> deadlines = new ArrayList<>(); private List<Deadline> deadlines = new ArrayList<>();
//Описание гранта
@NotNull
private String comment; private String comment;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) //Заявка на грант
@JoinColumn(name = "grant_id", unique = true) @ManyToOne
@Fetch(FetchMode.SUBSELECT) @JoinColumn(name = "file_id")
private List<FileData> files = new ArrayList<>(); private FileData application;
@ManyToOne(cascade = CascadeType.ALL) @ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "project_id") @JoinColumn(name = "project_id")
private Project project; private Project project;
@ManyToMany(fetch = FetchType.EAGER)
private Set<User> authors = new HashSet<>();
@NotNull
@ManyToOne
@JoinColumn(name = "leader_id")
private User leader;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "grants_papers",
joinColumns = {@JoinColumn(name = "grant_id")},
inverseJoinColumns = {@JoinColumn(name = "paper_id")})
@Fetch(FetchMode.SUBSELECT)
private List<Paper> papers = new ArrayList<>();
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "grant_id")
private List<Event> events = new ArrayList<>();
public GrantStatus getStatus() { public GrantStatus getStatus() {
return status; return status;
} }
@ -132,28 +90,18 @@ public class Grant extends BaseEntity implements UserActivity, EventSource {
this.comment = comment; this.comment = comment;
} }
public List<FileData> getFiles() { public FileData getApplication() {
return files; return application;
} }
public void setFiles(List<FileData> files) { public void setApplication(FileData application) {
this.files = files; this.application = application;
} }
public String getTitle() { public String getTitle() {
return title; return title;
} }
@Override
public List<User> getRecipients() {
return authors != null ? new ArrayList<>(authors) : Collections.emptyList();
}
@Override
public void addObjectToEvent(Event event) {
event.setGrant(this);
}
public void setTitle(String title) { public void setTitle(String title) {
this.title = title; this.title = title;
} }
@ -166,43 +114,6 @@ public class Grant extends BaseEntity implements UserActivity, EventSource {
this.project = project; this.project = project;
} }
public Set<User> getAuthors() {
return authors;
}
public void setAuthors(Set<User> authors) {
this.authors = authors;
}
@Override
public Set<User> getActivityUsers() {
return getAuthors();
}
public User getLeader() {
return leader;
}
public void setLeader(User leader) {
this.leader = leader;
}
public List<Paper> getPapers() {
return papers;
}
public void setPapers(List<Paper> papers) {
this.papers = papers;
}
public List<Event> getEvents() {
return events;
}
public void setEvents(List<Event> events) {
this.events = events;
}
public Optional<Deadline> getNextDeadline() { public Optional<Deadline> getNextDeadline() {
return deadlines return deadlines
.stream() .stream()

View File

@ -2,122 +2,67 @@ package ru.ulstu.grant.model;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotEmpty; import org.hibernate.validator.constraints.NotEmpty;
import org.apache.commons.lang3.StringUtils; import ru.ulstu.deadline.model.DeadlineDto;
import ru.ulstu.deadline.model.Deadline; import ru.ulstu.grant.model.Grant;
import ru.ulstu.file.model.FileDataDto;
import ru.ulstu.name.NameContainer;
import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.project.model.ProjectDto; import ru.ulstu.project.model.ProjectDto;
import ru.ulstu.user.model.UserDto;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static ru.ulstu.core.util.StreamApiUtils.convert; import static ru.ulstu.core.util.StreamApiUtils.convert;
public class GrantDto extends NameContainer { public class GrantDto {
private final static int MAX_AUTHORS_LENGTH = 60;
private Integer id; private Integer id;
@NotEmpty @NotEmpty
private String title; private String title;
private Grant.GrantStatus status; private Grant.GrantStatus status;
private List<Deadline> deadlines = new ArrayList<>(); private List<DeadlineDto> deadlines = new ArrayList<>();
private String comment; private String comment;
private List<FileDataDto> files = new ArrayList<>(); private String applicationFileName;
private ProjectDto project; private ProjectDto project;
private Set<Integer> authorIds;
private Set<UserDto> authors;
private Integer leaderId;
private boolean wasLeader;
private boolean hasAge;
private boolean hasDegree;
private boolean hasBAKPapers;
private boolean hasScopusPapers;
private List<Integer> paperIds = new ArrayList<>();
private List<PaperDto> papers = new ArrayList<>();
private List<Integer> removedDeadlineIds = new ArrayList<>();
public GrantDto() { public GrantDto() {
deadlines.add(new Deadline()); deadlines.add(new DeadlineDto());
} }
@JsonCreator @JsonCreator
public GrantDto(@JsonProperty("id") Integer id, public GrantDto(@JsonProperty("id") Integer id,
@JsonProperty("title") String title, @JsonProperty("title") String title,
@JsonProperty("status") Grant.GrantStatus status, @JsonProperty("status") Grant.GrantStatus status,
@JsonProperty("deadlines") List<Deadline> deadlines, @JsonProperty("deadlines") List<DeadlineDto> deadlines,
@JsonProperty("comment") String comment, @JsonProperty("comment") String comment,
@JsonProperty("files") List<FileDataDto> files, @JsonProperty("project") ProjectDto project) {
@JsonProperty("project") ProjectDto project,
@JsonProperty("authorIds") Set<Integer> authorIds,
@JsonProperty("authors") Set<UserDto> authors,
@JsonProperty("leaderId") Integer leaderId,
@JsonProperty("wasLeader") boolean wasLeader,
@JsonProperty("hasAge") boolean hasAge,
@JsonProperty("hasDegree") boolean hasDegree,
@JsonProperty("paperIds") List<Integer> paperIds,
@JsonProperty("papers") List<PaperDto> papers) {
this.id = id; this.id = id;
this.title = title; this.title = title;
this.status = status; this.status = status;
this.deadlines = deadlines; this.deadlines = deadlines;
this.comment = comment; this.comment = comment;
this.files = files; this.applicationFileName = null;
this.project = project; this.project = project;
this.authorIds = authorIds;
this.authors = authors;
this.leaderId = leaderId;
this.wasLeader = wasLeader;
this.hasAge = hasAge;
this.hasDegree = hasDegree;
this.paperIds = paperIds;
this.papers = papers;
} }
public GrantDto(Grant grant) { public GrantDto(Grant grant) {
this.id = grant.getId(); this.id = grant.getId();
this.title = grant.getTitle(); this.title = grant.getTitle();
this.status = grant.getStatus(); this.status = grant.getStatus();
this.deadlines = grant.getDeadlines(); this.deadlines = convert(grant.getDeadlines(), DeadlineDto::new);
this.comment = grant.getComment(); this.comment = grant.getComment();
this.files = convert(grant.getFiles(), FileDataDto::new);
this.project = grant.getProject() == null ? null : new ProjectDto(grant.getProject()); this.project = grant.getProject() == null ? null : new ProjectDto(grant.getProject());
this.authorIds = convert(grant.getAuthors(), user -> user.getId()); this.applicationFileName = grant.getApplication() == null ? null : grant.getApplication().getName();
this.authors = convert(grant.getAuthors(), UserDto::new);
this.leaderId = grant.getLeader().getId();
this.wasLeader = false;
this.hasAge = false;
this.hasDegree = false;
this.paperIds = convert(grant.getPapers(), paper -> paper.getId());
this.papers = convert(grant.getPapers(), PaperDto::new);
}
public GrantDto(String grantTitle, Date deadLineDate) {
this.title = grantTitle;
deadlines.add(new Deadline(deadLineDate, "Окончание приёма заявок"));
status = Grant.GrantStatus.LOADED_FROM_KIAS;
} }
public Integer getId() { public Integer getId() {
return id; return id;
} }
public void setId(Integer id) { public void setId(Integer id) {this.id = id;}
this.id = id;
}
public String getTitle() { public String getTitle() {
return title; return title;
} }
public void setTitle(String title) { public void setTitle(String title) {this.title = title;}
this.title = title;
}
public Grant.GrantStatus getStatus() { public Grant.GrantStatus getStatus() {
return status; return status;
@ -127,11 +72,11 @@ public class GrantDto extends NameContainer {
this.status = status; this.status = status;
} }
public List<Deadline> getDeadlines() { public List<DeadlineDto> getDeadlines() {
return deadlines; return deadlines;
} }
public void setDeadlines(List<Deadline> deadlines) { public void setDeadlines(List<DeadlineDto> deadlines) {
this.deadlines = deadlines; this.deadlines = deadlines;
} }
@ -139,118 +84,18 @@ public class GrantDto extends NameContainer {
return comment; return comment;
} }
public void setComment(String comment) { public void setComment(String comment) {this.comment = comment;}
this.comment = comment;
}
public List<FileDataDto> getFiles() {
return files;
}
public void setFiles(List<FileDataDto> files) {
this.files = files;
}
public ProjectDto getProject() { public ProjectDto getProject() {
return project; return project;
} }
public void setProject(ProjectDto project) { public void setProject(ProjectDto project) {this.project = project;}
this.project = project;
public String getApplicationFileName() {
return applicationFileName;
} }
public Set<Integer> getAuthorIds() { public void setApplicationFileName(String applicationFileName) {
return authorIds; this.applicationFileName = applicationFileName;}
}
public void setAuthorIds(Set<Integer> authorIds) {
this.authorIds = authorIds;
}
public Set<UserDto> getAuthors() {
return authors;
}
public void setAuthors(Set<UserDto> authors) {
this.authors = authors;
}
public String getAuthorsString() {
return StringUtils.abbreviate(authors
.stream()
.map(author -> author.getLastName())
.collect(Collectors.joining(", ")), MAX_AUTHORS_LENGTH);
}
public Integer getLeaderId() {
return leaderId;
}
public void setLeaderId(Integer leaderId) {
this.leaderId = leaderId;
}
public boolean isWasLeader() {
return wasLeader;
}
public void setWasLeader(boolean wasLeader) {
this.wasLeader = wasLeader;
}
public boolean isHasAge() {
return hasAge;
}
public void setHasAge(boolean hasAge) {
this.hasAge = hasAge;
}
public boolean isHasDegree() {
return hasDegree;
}
public void setHasDegree(boolean hasDegree) {
this.hasDegree = hasDegree;
}
public List<Integer> getPaperIds() {
return paperIds;
}
public void setPaperIds(List<Integer> paperIds) {
this.paperIds = paperIds;
}
public List<PaperDto> getPapers() {
return papers;
}
public void setPapers(List<PaperDto> papers) {
this.papers = papers;
}
public List<Integer> getRemovedDeadlineIds() {
return removedDeadlineIds;
}
public void setRemovedDeadlineIds(List<Integer> removedDeadlineIds) {
this.removedDeadlineIds = removedDeadlineIds;
}
public boolean isHasBAKPapers() {
return hasBAKPapers;
}
public void setHasBAKPapers(boolean hasBAKPapers) {
this.hasBAKPapers = hasBAKPapers;
}
public boolean isHasScopusPapers() {
return hasScopusPapers;
}
public void setHasScopusPapers(boolean hasScopusPapers) {
this.hasScopusPapers = hasScopusPapers;
}
} }

View File

@ -0,0 +1,19 @@
package ru.ulstu.grant.model;
public class GrantStatusDto {
private final String id;
private final String name;
public GrantStatusDto(Grant.GrantStatus status) {
this.id = status.name();
this.name = status.getStatusName();
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}

View File

@ -1,55 +0,0 @@
package ru.ulstu.grant.page;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlTableRow;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
public class KiasPage {
private final static String KIAS_GRANT_DATE_FORMAT = "dd.MM.yyyy HH:mm";
private final HtmlPage page;
public KiasPage(HtmlPage page) {
this.page = page;
}
public boolean goToNextPage() {
try {
HtmlElement nextPageLink = page.getHtmlElementById("js-ctrlNext");
if (nextPageLink.isDisplayed()) {
nextPageLink.click();
return true;
}
} finally {
return false;
}
}
public List<DomNode> getPageOfGrants() {
return page.getByXPath("/html/body/div[2]/div/div[2]/main/div[1]/table/tbody/tr");
}
public String getGrantTitle(DomNode grant) {
return ((DomNode) grant.getFirstByXPath("td[2]")).getTextContent() + " "
+ ((DomNode) grant.getFirstByXPath("td[@class='tertiary']/a")).getTextContent();
}
public Date parseDeadLineDate(DomNode grantElement) throws ParseException {
String deadlineDate = getFirstDeadline(grantElement); //10.06.2019 23:59
SimpleDateFormat formatter = new SimpleDateFormat(KIAS_GRANT_DATE_FORMAT);
return formatter.parse(deadlineDate);
}
private String getFirstDeadline(DomNode grantElement) {
return ((DomNode) grantElement.getFirstByXPath("td[5]")).getTextContent();
}
public boolean isTableRowGrantLine(DomNode grantElement) {
return !((HtmlTableRow) grantElement).getAttribute("class").contains("pagerSavedHeightSpacer");
}
}

View File

@ -1,25 +1,8 @@
package ru.ulstu.grant.repository; package ru.ulstu.grant.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.repository.query.Param;
import ru.ulstu.grant.model.Grant; import ru.ulstu.grant.model.Grant;
import ru.ulstu.name.BaseRepository;
import java.util.List; public interface GrantRepository extends JpaRepository<Grant, Integer> {
public interface GrantRepository extends JpaRepository<Grant, Integer>, BaseRepository {
List<Grant> findByStatus(Grant.GrantStatus status);
Grant findFirstByTitle(String title);
Grant findGrantById(Integer grantId);
@Override
@Query("SELECT title FROM Grant g WHERE (g.title = :name) AND (:id IS NULL OR g.id != :id) ")
List<String> findByNameAndNotId(@Param("name") String name, @Param("id") Integer id);
@Query("SELECT g FROM Grant g WHERE (g.status <> 'SKIPPED') AND (g.status <> 'COMPLETED')")
List<Grant> findAllActive();
} }

View File

@ -1,72 +0,0 @@
package ru.ulstu.grant.service;
import org.springframework.stereotype.Service;
import ru.ulstu.core.util.DateUtils;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.user.model.User;
import ru.ulstu.user.service.MailService;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Service
public class GrantNotificationService {
private final static int DAYS_TO_DEADLINE_NOTIFICATION = 7;
private final static String TEMPLATE_DEADLINE = "grantDeadlineNotification";
private final static String TEMPLATE_CREATE = "grantCreateNotification";
private final static String TEMPLATE_AUTHORS_CHANGED = "grantAuthorsChangeNotification";
private final static String TEMPLATE_LEADER_CHANGED = "grantLeaderChangeNotification";
private final static String TITLE_DEADLINE = "Приближается дедлайн гранта: %s";
private final static String TITLE_CREATE = "Создан грант: %s";
private final static String TITLE_AUTHORS_CHANGED = "Изменился состав рабочей группы гранта: %s";
private final static String TITLE_LEADER_CHANGED = "Изменился руководитель гранта: %s";
private final MailService mailService;
public GrantNotificationService(MailService mailService) {
this.mailService = mailService;
}
public void sendDeadlineNotifications(List<Grant> grants, boolean isDeadlineBeforeWeek) {
Date now = DateUtils.addDays(new Date(), DAYS_TO_DEADLINE_NOTIFICATION);
grants.stream()
.filter(grant -> needToSendDeadlineNotification(grant, now, isDeadlineBeforeWeek))
.forEach(grant -> sendMessageDeadline(grant));
}
private boolean needToSendDeadlineNotification(Grant grant, Date compareDate, boolean isDeadlineBeforeWeek) {
return (grant.getNextDeadline().isPresent())
&& (compareDate.before(grant.getNextDeadline().get().getDate()) && isDeadlineBeforeWeek
|| compareDate.after(grant.getNextDeadline().get().getDate()) && !isDeadlineBeforeWeek)
&& grant.getNextDeadline().get().getDate().after(new Date());
}
private void sendMessageDeadline(Grant grant) {
Map<String, Object> variables = Map.of("grant", grant);
sendForAllAuthors(variables, grant, TEMPLATE_DEADLINE, String.format(TITLE_DEADLINE, grant.getTitle()));
}
public void sendCreateNotification(Grant grant) {
Map<String, Object> variables = Map.of("grant", grant);
sendForAllAuthors(variables, grant, TEMPLATE_CREATE, String.format(TITLE_CREATE, grant.getTitle()));
}
public void sendAuthorsChangeNotification(Grant grant, Set<User> oldAuthors) {
Map<String, Object> variables = Map.of("grant", grant, "oldAuthors", oldAuthors);
sendForAllAuthors(variables, grant, TEMPLATE_AUTHORS_CHANGED, String.format(TITLE_AUTHORS_CHANGED, grant.getTitle()));
}
public void sendLeaderChangeNotification(Grant grant, User oldLeader) {
Map<String, Object> variables = Map.of("grant", grant, "oldLeader", oldLeader);
sendForAllAuthors(variables, grant, TEMPLATE_LEADER_CHANGED, String.format(TITLE_LEADER_CHANGED, grant.getTitle()));
}
private void sendForAllAuthors(Map<String, Object> variables, Grant grant, String template, String title) {
Set<User> allAuthors = grant.getAuthors();
allAuthors.forEach(author -> mailService.sendEmailFromTemplate(variables, author, template, title));
mailService.sendEmailFromTemplate(variables, grant.getLeader(), template, title);
}
}

View File

@ -1,41 +0,0 @@
package ru.ulstu.grant.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
public class GrantScheduler {
private final static boolean IS_DEADLINE_NOTIFICATION_BEFORE_WEEK = true;
private final Logger log = LoggerFactory.getLogger(GrantScheduler.class);
private final GrantNotificationService grantNotificationService;
private final GrantService grantService;
public GrantScheduler(GrantNotificationService grantNotificationService,
GrantService grantService) {
this.grantNotificationService = grantNotificationService;
this.grantService = grantService;
}
@Scheduled(cron = "0 0 8 * * MON", zone = "Europe/Samara")
public void checkDeadlineBeforeWeek() {
log.debug("GrantScheduler.checkDeadlineBeforeWeek started");
grantNotificationService.sendDeadlineNotifications(grantService.findAllActive(), IS_DEADLINE_NOTIFICATION_BEFORE_WEEK);
log.debug("GrantScheduler.checkDeadlineBeforeWeek finished");
}
@Scheduled(cron = "0 0 8 * * ?", zone = "Europe/Samara")
public void loadGrantsFromKias() {
log.debug("GrantScheduler.loadGrantsFromKias started");
// try {
// grantService.createFromKias();
// } catch (ParseException | IOException e) {
// e.printStackTrace();
// }
log.debug("GrantScheduler.loadGrantsFromKias finished");
}
}

View File

@ -1,86 +1,44 @@
package ru.ulstu.grant.service; package ru.ulstu.grant.service;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
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 org.springframework.validation.Errors;
import ru.ulstu.core.util.DateUtils;
import ru.ulstu.deadline.model.Deadline; import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.deadline.service.DeadlineService; import ru.ulstu.deadline.service.DeadlineService;
import ru.ulstu.file.model.FileDataDto;
import ru.ulstu.file.service.FileService; import ru.ulstu.file.service.FileService;
import ru.ulstu.grant.model.Grant; import ru.ulstu.grant.model.Grant;
import ru.ulstu.grant.model.GrantDto; import ru.ulstu.grant.model.GrantDto;
import ru.ulstu.grant.repository.GrantRepository; import ru.ulstu.grant.repository.GrantRepository;
import ru.ulstu.name.BaseService; import ru.ulstu.project.model.Project;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.paper.service.PaperService;
import ru.ulstu.ping.service.PingService;
import ru.ulstu.project.model.ProjectDto; import ru.ulstu.project.model.ProjectDto;
import ru.ulstu.project.service.ProjectService; import ru.ulstu.project.service.ProjectService;
import ru.ulstu.timeline.service.EventService;
import ru.ulstu.user.model.User;
import ru.ulstu.user.service.UserService;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.time.temporal.ChronoUnit;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
import static org.springframework.util.ObjectUtils.isEmpty; import static org.springframework.util.ObjectUtils.isEmpty;
import static ru.ulstu.core.util.StreamApiUtils.convert; import static ru.ulstu.core.util.StreamApiUtils.convert;
import static ru.ulstu.grant.model.Grant.GrantStatus.APPLICATION; import static ru.ulstu.grant.model.Grant.GrantStatus.APPLICATION;
@Service @Service
public class GrantService extends BaseService { public class GrantService {
private final Logger log = LoggerFactory.getLogger(GrantService.class); private final static int MAX_DISPLAY_SIZE = 40;
private final GrantRepository grantRepository; private final GrantRepository grantRepository;
private final ProjectService projectService; private final ProjectService projectService;
private final DeadlineService deadlineService; private final DeadlineService deadlineService;
private final FileService fileService; private final FileService fileService;
private final UserService userService;
private final PaperService paperService;
private final EventService eventService;
private final GrantNotificationService grantNotificationService;
private final KiasService kiasService;
private final PingService pingService;
public GrantService(GrantRepository grantRepository, public GrantService(GrantRepository grantRepository,
FileService fileService, FileService fileService,
DeadlineService deadlineService, DeadlineService deadlineService,
ProjectService projectService, ProjectService projectService) {
UserService userService,
PaperService paperService,
EventService eventService,
GrantNotificationService grantNotificationService,
KiasService kiasService,
PingService pingService) {
this.grantRepository = grantRepository; this.grantRepository = grantRepository;
this.kiasService = kiasService; this.projectService = projectService;
this.baseRepository = grantRepository;
this.fileService = fileService; this.fileService = fileService;
this.deadlineService = deadlineService; this.deadlineService = deadlineService;
this.projectService = projectService;
this.userService = userService;
this.paperService = paperService;
this.eventService = eventService;
this.grantNotificationService = grantNotificationService;
this.pingService = pingService;
}
public GrantDto getExistGrantById(Integer id) {
return new GrantDto(findById(id));
} }
public List<Grant> findAll() { public List<Grant> findAll() {
@ -88,16 +46,20 @@ public class GrantService extends BaseService {
} }
public List<GrantDto> findAllDto() { public List<GrantDto> findAllDto() {
return convert(findAll(), GrantDto::new); List<GrantDto> grants = convert(findAll(), GrantDto::new);
grants.forEach(grantDto -> grantDto.setTitle(StringUtils.abbreviate(grantDto.getTitle(), MAX_DISPLAY_SIZE)));
return grants;
}
public GrantDto findOneDto(Integer id) {
return new GrantDto(grantRepository.findOne(id));
} }
@Transactional @Transactional
public Grant create(GrantDto grantDto) throws IOException { public Integer create(GrantDto grantDto) throws IOException {
Grant newGrant = copyFromDto(new Grant(), grantDto); Grant newGrant = copyFromDto(new Grant(), grantDto);
newGrant = grantRepository.save(newGrant); newGrant = grantRepository.save(newGrant);
eventService.createFromObject(newGrant, Collections.emptyList(), false, "гранта"); return newGrant.getId();
grantNotificationService.sendCreateNotification(newGrant);
return newGrant;
} }
private Grant copyFromDto(Grant grant, GrantDto grantDto) throws IOException { private Grant copyFromDto(Grant grant, GrantDto grantDto) throws IOException {
@ -108,296 +70,59 @@ public class GrantService extends BaseService {
grant.setProject(projectService.findById(grantDto.getProject().getId())); grant.setProject(projectService.findById(grantDto.getProject().getId()));
} }
grant.setDeadlines(deadlineService.saveOrCreate(grantDto.getDeadlines())); grant.setDeadlines(deadlineService.saveOrCreate(grantDto.getDeadlines()));
if (!grant.getFiles().isEmpty()) { if (grantDto.getApplicationFileName() != null) {
grant.setFiles(fileService.saveOrCreate(grantDto.getFiles().stream() grant.setApplication(fileService.createFileFromTmp(grantDto.getApplicationFileName()));
.filter(f -> !f.isDeleted())
.collect(toList())));
}
grant.getAuthors().clear();
if (grantDto.getAuthorIds() != null && !grantDto.getAuthorIds().isEmpty()) {
grantDto.getAuthorIds().forEach(authorIds -> grant.getAuthors().add(userService.findById(authorIds)));
}
if (grantDto.getLeaderId() != null) {
grant.setLeader(userService.findById(grantDto.getLeaderId()));
}
grant.getPapers().clear();
if (grantDto.getPaperIds() != null && !grantDto.getPaperIds().isEmpty()) {
grantDto.getPaperIds().forEach(paperIds -> grant.getPapers().add(paperService.findPaperById(paperIds)));
} }
return grant; return grant;
} }
public void createProject(GrantDto grantDto) {
public void createProject(GrantDto grantDto) throws IOException {
grantDto.setProject( grantDto.setProject(
new ProjectDto(projectService.save(new ProjectDto(grantDto.getTitle())))); new ProjectDto(projectService.save(new ProjectDto(grantDto.getTitle()))));
} }
@Transactional @Transactional
private Integer update(GrantDto grantDto) throws IOException { public Integer update(GrantDto grantDto) throws IOException {
Grant grant = findById(grantDto.getId()); Grant grant = grantRepository.findOne(grantDto.getId());
Set<User> oldAuthors = new HashSet<>(grant.getAuthors()); Grant.GrantStatus oldStatus = grant.getStatus();
User oldLeader = grant.getLeader(); if (grantDto.getApplicationFileName() != null && grant.getApplication() != null) {
for (FileDataDto file : grantDto.getFiles().stream() fileService.deleteFile(grant.getApplication());
.filter(f -> f.isDeleted() && f.getId() != null)
.collect(toList())) {
fileService.delete(file.getId());
} }
grantDto.getRemovedDeadlineIds().forEach(deadlineService::remove);
grantRepository.save(copyFromDto(grant, grantDto)); grantRepository.save(copyFromDto(grant, grantDto));
grant.getAuthors().forEach(author -> {
if (!oldAuthors.contains(author)) {
grantNotificationService.sendAuthorsChangeNotification(grant, oldAuthors);
}
});
oldAuthors.forEach(oldAuthor -> {
if (!grant.getAuthors().contains(oldAuthor)) {
grantNotificationService.sendAuthorsChangeNotification(grant, oldAuthors);
}
});
if (grant.getLeader() != oldLeader) {
grantNotificationService.sendLeaderChangeNotification(grant, oldLeader);
}
eventService.updateGrantDeadlines(grant);
return grant.getId(); return grant.getId();
} }
@Transactional @Transactional
public boolean delete(Integer grantId) throws IOException { public void delete(Integer grantId) throws IOException {
Grant grant = findById(grantId); Grant grant = grantRepository.findOne(grantId);
if (grant != null) { if (grant.getApplication() != null) {
grantRepository.delete(grant); fileService.deleteFile(grant.getApplication());
return true;
} }
return false; //возможно при удалении гранта будет удаляться и проект, к нему привязанный
grantRepository.delete(grant);
} }
public List<Grant.GrantStatus> getGrantStatuses() { public List<Grant.GrantStatus> getGrantStatuses() {
return Arrays.asList(Grant.GrantStatus.values()); return Arrays.asList(Grant.GrantStatus.values());
} }
public boolean save(GrantDto grantDto, Errors errors) throws IOException { @Transactional
grantDto.setName(grantDto.getTitle()); public Grant create(String title, Project project_id, Date deadlineDate) {
filterEmptyDeadlines(grantDto); Grant grant = new Grant();
checkEmptyDeadlines(grantDto, errors); grant.setTitle(title);
checkEmptyLeader(grantDto, errors); grant.setComment("Комментарий к гранту 1");
checkUniqueName(grantDto, errors, grantDto.getId(), "Грант с таким именем уже существует"); grant.setProject(project_id);
if (errors.hasErrors()) { grant.setStatus(APPLICATION);
return false; grant.getDeadlines().add(new Deadline(deadlineDate, "первый дедлайн"));
grant = grantRepository.save(grant);
return grant;
} }
public void save(GrantDto grantDto) throws IOException {
if (isEmpty(grantDto.getId())) { if (isEmpty(grantDto.getId())) {
create(grantDto); create(grantDto);
} else { } else {
update(grantDto); update(grantDto);
} }
return true;
}
private boolean saveFromKias(GrantDto grantDto) throws IOException {
grantDto.setName(grantDto.getTitle());
String title = checkUniqueName(grantDto, grantDto.getId()); //проверка уникальности имени
if (title != null) {
Grant grantFromDB = grantRepository.findFirstByTitle(title); //грант с таким же названием из бд
if (checkSameDeadline(grantDto, grantFromDB.getId())) { //если дедайны тоже совпадают
return false;
} else { //иначе грант уже был в системе, но в другом году, поэтому надо создать
create(grantDto);
return true;
}
} else { //иначе такого гранта ещё нет, поэтому надо создать
create(grantDto);
return true;
}
}
private void checkEmptyLeader(GrantDto grantDto, Errors errors) {
if (grantDto.getLeaderId().equals(-1)) {
errors.rejectValue("leaderId", "errorCode", "Укажите руководителя");
}
}
private void checkEmptyDeadlines(GrantDto grantDto, Errors errors) {
if (grantDto.getDeadlines().isEmpty()) {
errors.rejectValue("deadlines", "errorCode", "Не может быть пусто");
}
}
private boolean checkSameDeadline(GrantDto grantDto, Integer id) {
Date date = DateUtils.clearTime(grantDto.getDeadlines().get(0).getDate()); //дата с сайта киас
Date foundGrantDate = DateUtils.clearTime(deadlineService.findByGrantIdAndDate(id, date));
return foundGrantDate != null && foundGrantDate.compareTo(date) == 0;
}
public List<User> getGrantAuthors(GrantDto grantDto) {
List<User> filteredUsers = userService.filterByAgeAndDegree(grantDto.isHasAge(), grantDto.isHasDegree());
if (grantDto.isWasLeader()) {
filteredUsers = checkContains(filteredUsers, getCompletedGrantLeaders());
}
if (grantDto.isHasBAKPapers()) {
filteredUsers = checkContains(filteredUsers, getBAKAuthors());
}
if (grantDto.isHasScopusPapers()) {
filteredUsers = checkContains(filteredUsers, getScopusAuthors());
}
return filteredUsers;
}
private List<User> checkContains(List<User> filteredUsers, List<User> checkUsers) {
return filteredUsers.stream()
.filter(checkUsers::contains)
.collect(toList());
}
private List<User> getCompletedGrantLeaders() {
return grantRepository.findByStatus(Grant.GrantStatus.COMPLETED)
.stream()
.map(Grant::getLeader)
.collect(toList());
}
public List<PaperDto> getGrantPapers(List<Integer> paperIds) {
return paperService.findAllSelect(paperIds);
}
public List<PaperDto> getAllUncompletedPapers() {
return paperService.findAllNotCompleted();
}
public List<PaperDto> attachPaper(GrantDto grantDto) {
if (!grantDto.getPaperIds().isEmpty()) {
grantDto.getPapers().clear();
grantDto.setPapers(getGrantPapers(grantDto.getPaperIds()));
} else {
grantDto.getPapers().clear();
}
return grantDto.getPapers();
}
public GrantDto removeDeadline(GrantDto grantDto, Integer deadlineId) {
if (grantDto.getDeadlines().get(deadlineId).getId() != null) {
grantDto.getRemovedDeadlineIds().add(grantDto.getDeadlines().get(deadlineId).getId());
}
grantDto.getDeadlines().remove((int) deadlineId);
return grantDto;
}
private List<User> getCompletedPapersAuthors(Paper.PaperType type) {
List<Paper> papers = paperService.findAllCompletedByType(type);
return papers.stream()
.filter(paper -> paper.getAuthors() != null)
.flatMap(paper -> paper.getAuthors().stream())
.collect(toList());
}
private List<User> getBAKAuthors() {
return getCompletedPapersAuthors(Paper.PaperType.VAK)
.stream()
.distinct()
.collect(toList());
}
private List<User> getScopusAuthors() {
List<User> authors = getCompletedPapersAuthors(Paper.PaperType.SCOPUS);
return authors
.stream()
.filter(author -> Collections.frequency(authors, author) > 3)
.collect(toList());
}
public List<Deadline> filterEmptyDeadlines(GrantDto grantDto) {
grantDto.setDeadlines(grantDto.getDeadlines().stream()
.filter(dto -> dto.getDate() != null || !StringUtils.isEmpty(dto.getDescription()))
.collect(Collectors.toList()));
return grantDto.getDeadlines();
}
@Transactional
public void createFromKias() throws IOException, ParseException {
for (GrantDto grantDto : kiasService.getNewGrantsDto()) {
if (saveFromKias(grantDto)) {
log.debug("GrantScheduler.loadGrantsFromKias new grant was loaded");
} else {
log.debug("GrantScheduler.loadGrantsFromKias grant wasn't loaded, cause it's already exists");
}
}
}
public List<GrantDto> findAllActiveDto() {
return convert(findAllActive(), GrantDto::new);
}
public List<Grant> findAllActive() {
return grantRepository.findAllActive();
}
public Grant findById(Integer id) {
return grantRepository.getOne(id);
}
@Transactional
public void ping(int grantId) throws IOException {
pingService.addPing(findById(grantId));
}
public void save(Grant grant) {
if (isEmpty(grant.getId())) {
create(grant);
} else {
update(grant);
}
}
@Transactional
public Grant create(Grant grant) {
Grant newGrant = grantRepository.save(grant);
grantNotificationService.sendCreateNotification(newGrant);
return newGrant;
}
@Transactional
public Integer update(Grant newGrant) {
Grant oldGrant = grantRepository.getOne(newGrant.getId());
//Grant.GrantStatus oldStatus = oldGrant.getStatus();
Set<User> oldAuthors = new HashSet<>(oldGrant.getAuthors());
newGrant = grantRepository.save(newGrant);
for (User author : newGrant.getAuthors()) {
if (!oldAuthors.contains(author)) {
grantNotificationService.sendCreateNotification(newGrant);
}
}
// if (newGrant.getStatus() != oldStatus) {
// grantNotificationService.statusChangeNotification(newPaper, oldStatus);
// }
return newGrant.getId();
}
public void createByTitle(String newGrantTitle) {
Grant grant = new Grant();
grant.setTitle(newGrantTitle);
grant.setStatus(APPLICATION);
grant.getAuthors().add(userService.getCurrentUser());
grant.setLeader(userService.getCurrentUser());
grant.getDeadlines().add(deadlineService.createWithOffset(new Date(), 1, ChronoUnit.WEEKS));
create(grant);
}
public List<Grant> findAllActiveByCurrentUser() {
return findAllActive()
.stream()
.filter(grant -> grant.getAuthors().contains(userService.getCurrentUser()) ||
grant.getLeader().equals(userService.getCurrentUser()))
.collect(toList());
}
public void delete(List<Grant> grants) {
grants.forEach(grant -> delete(grant));
}
public void delete(Grant grant) {
deadlineService.delete(grant.getDeadlines());
grantRepository.delete(grant);
} }
} }

View File

@ -1,73 +0,0 @@
package ru.ulstu.grant.service;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.springframework.stereotype.Service;
import ru.ulstu.configuration.ApplicationProperties;
import ru.ulstu.grant.model.GrantDto;
import ru.ulstu.grant.page.KiasPage;
import ru.ulstu.user.service.UserService;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
@Service
public class KiasService {
private final static String BASE_URL = "https://www.rfbr.ru/rffi/ru/contest_search?CONTEST_STATUS_ID=%s&CONTEST_TYPE=%s&CONTEST_YEAR=%s";
private final static String CONTEST_STATUS_ID = "1";
private final static String CONTEST_TYPE = "-1";
private final UserService userService;
public KiasService(UserService userService,
ApplicationProperties applicationProperties) {
this.userService = userService;
}
public List<GrantDto> getNewGrantsDto() throws ParseException, IOException {
Integer leaderId = userService.findOneByLoginIgnoreCase("admin").getId();
List<GrantDto> grants = new ArrayList<>();
try (WebClient webClient = new WebClient()) {
webClient.setJavaScriptTimeout(60 * 1000);
webClient.getOptions().setThrowExceptionOnScriptError(false);
for (Integer year : generateGrantYears()) {
final HtmlPage page = webClient.getPage(String.format(BASE_URL, CONTEST_STATUS_ID, CONTEST_TYPE, year));
grants.addAll(getKiasGrants(page));
}
}
grants.forEach(grantDto -> grantDto.setLeaderId(leaderId));
return grants;
}
private List<GrantDto> getKiasGrants(HtmlPage page) throws ParseException {
List<GrantDto> newGrants = new ArrayList<>();
KiasPage kiasPage = new KiasPage(page);
do {
newGrants.addAll(getGrantsFromPage(kiasPage));
} while (kiasPage.goToNextPage()); //проверка существования следующей страницы с грантами
return newGrants;
}
private List<GrantDto> getGrantsFromPage(KiasPage kiasPage) throws ParseException {
List<GrantDto> grants = new ArrayList<>();
for (DomNode grantElement : kiasPage.getPageOfGrants()) {
if (kiasPage.isTableRowGrantLine(grantElement)) {
GrantDto grantDto = new GrantDto(
kiasPage.getGrantTitle(grantElement),
kiasPage.parseDeadLineDate(grantElement));
grants.add(grantDto);
}
}
return grants;
}
private List<Integer> generateGrantYears() {
return Arrays.asList(Calendar.getInstance().get(Calendar.YEAR),
Calendar.getInstance().get(Calendar.YEAR) + 1);
}
}

View File

@ -1,23 +0,0 @@
package ru.ulstu.index.controller;
import io.swagger.v3.oas.annotations.Hidden;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import ru.ulstu.core.controller.AdviceController;
import ru.ulstu.user.service.UserService;
@Controller()
@RequestMapping(value = "/index")
@Hidden
public class IndexController extends AdviceController {
public IndexController(UserService userService) {
super(userService);
}
@GetMapping
public void currentUser(ModelMap modelMap) {
//нужен здесь для добавления параметров на стартовой странице
}
}

View File

@ -1,25 +0,0 @@
package ru.ulstu.index.model;
public class Section {
private final String title;
private final String image;
private final String href;
public Section(String title, String href, String image) {
this.title = title;
this.image = image;
this.href = href;
}
public String getTitle() {
return title;
}
public String getImage() {
return image;
}
public String getHref() {
return href;
}
}

View File

@ -1,9 +0,0 @@
package ru.ulstu.name;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface BaseRepository {
List<String> findByNameAndNotId(@Param("name") String name, @Param("id") Integer id);
}

View File

@ -1,36 +0,0 @@
package ru.ulstu.name;
import org.springframework.stereotype.Service;
import org.springframework.validation.Errors;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Service
public abstract class BaseService {
public BaseRepository baseRepository;
protected void checkUniqueName(NameContainer nameContainer, Errors errors, Integer id, String errorMessage) {
if (nameContainer.getName().equals(getUnique(baseRepository.findByNameAndNotId(nameContainer.getName(), id)))) {
errors.rejectValue("title", "errorCode", errorMessage);
}
}
protected String checkUniqueName(NameContainer nameContainer, Integer id) {
String foundName = getUnique(baseRepository.findByNameAndNotId(nameContainer.getName(), id));
if (nameContainer.getName().equals(foundName)) {
return foundName;
}
return null;
}
private String getUnique(List<String> names) {
return Optional.ofNullable(names)
.orElse(new ArrayList<>())
.stream()
.findAny()
.orElse(null);
}
}

View File

@ -1,14 +0,0 @@
package ru.ulstu.name;
public abstract class NameContainer {
private String name = "";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -9,10 +9,10 @@ import ru.ulstu.odin.service.OdinService;
public abstract class OdinController<L, E extends OdinDto> { public abstract class OdinController<L, E extends OdinDto> {
public static final String META_LIST_URL = "/meta/list"; public static final String META_LIST_URL = "/meta/list";
private static final String META_ELEMENT_URL = "/meta/element"; public static final String META_ELEMENT_URL = "/meta/element";
private final Class<L> listDtoClass; private Class<L> listDtoClass;
private final Class<E> elementDtoClass; private Class<E> elementDtoClass;
@Autowired @Autowired
private OdinService<L, E> odinService; private OdinService<L, E> odinService;

View File

@ -3,7 +3,6 @@ package ru.ulstu.odin.model;
import ru.ulstu.core.error.OdinException; import ru.ulstu.core.error.OdinException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@ -15,9 +14,9 @@ public class OdinCollectionField extends OdinField {
ParameterizedType genericType = (ParameterizedType) field.getGenericType(); ParameterizedType genericType = (ParameterizedType) field.getGenericType();
Type fieldElementClass = genericType.getActualTypeArguments()[0]; Type fieldElementClass = genericType.getActualTypeArguments()[0];
try { try {
OdinDto someInstance = (OdinDto) ((Class) (fieldElementClass)).getDeclaredConstructor().newInstance(); OdinDto someInstance = (OdinDto) ((Class) (fieldElementClass)).newInstance();
this.path = someInstance.getControllerPath(); this.path = someInstance.getControllerPath();
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { } catch (IllegalAccessException | InstantiationException e) {
throw new OdinException(String.format("Can't create new instance, check default constructor of %s", throw new OdinException(String.format("Can't create new instance, check default constructor of %s",
fieldElementClass.getTypeName())); fieldElementClass.getTypeName()));
} }

View File

@ -1,14 +1,14 @@
package ru.ulstu.odin.model; package ru.ulstu.odin.model;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank; import org.hibernate.validator.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty; import org.hibernate.validator.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import ru.ulstu.core.error.OdinException; import ru.ulstu.core.error.OdinException;
import ru.ulstu.odin.model.annotation.OdinCaption; import ru.ulstu.odin.model.annotation.OdinCaption;
import ru.ulstu.odin.model.annotation.OdinReadOnly; import ru.ulstu.odin.model.annotation.OdinReadOnly;
import ru.ulstu.odin.model.annotation.OdinVisible; import ru.ulstu.odin.model.annotation.OdinVisible;
import javax.validation.constraints.NotNull;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -32,15 +32,15 @@ public abstract class OdinField implements Comparable {
} }
} }
private final OdinFieldType fieldType; private Field field;
private final String fieldName; protected final OdinFieldType fieldType;
private final String caption; protected final String fieldName;
private final OdinVisible.OdinVisibleType visible; protected final String caption;
private final boolean readOnly; protected final OdinVisible.OdinVisibleType visible;
private final boolean notEmpty; protected final boolean readOnly;
private final Field field; protected final boolean notEmpty;
OdinField(Field field, OdinFieldType fieldType) { public OdinField(Field field, OdinFieldType fieldType) {
this.field = field; this.field = field;
this.fieldName = getFieldName(field); this.fieldName = getFieldName(field);
this.caption = Optional.ofNullable(getValueFromAnnotation(OdinCaption.class, "value")) this.caption = Optional.ofNullable(getValueFromAnnotation(OdinCaption.class, "value"))
@ -93,7 +93,7 @@ public abstract class OdinField implements Comparable {
} }
} }
<T> T getValue(Class<? extends Annotation> annotationClass, String valueName, Class<T> clazz) { protected <T> T getValue(Class<? extends Annotation> annotationClass, String valueName, Class<T> clazz) {
if (field.isAnnotationPresent(annotationClass)) { if (field.isAnnotationPresent(annotationClass)) {
return cast(getValueFromAnnotation(annotationClass, valueName), clazz); return cast(getValueFromAnnotation(annotationClass, valueName), clazz);
} }
@ -126,12 +126,8 @@ public abstract class OdinField implements Comparable {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) { if (this == o) return true;
return true; if (o == null || getClass() != o.getClass()) return false;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
OdinField odinField = (OdinField) o; OdinField odinField = (OdinField) o;
return Objects.equals(fieldName, odinField.fieldName); return Objects.equals(fieldName, odinField.fieldName);
} }

View File

@ -3,7 +3,6 @@ package ru.ulstu.odin.model;
import ru.ulstu.core.error.OdinException; import ru.ulstu.core.error.OdinException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
public class OdinObjectField extends OdinField { public class OdinObjectField extends OdinField {
@ -13,9 +12,9 @@ public class OdinObjectField extends OdinField {
super(field, OdinFieldType.OBJECT); super(field, OdinFieldType.OBJECT);
Type fieldElementClass = field.getType(); Type fieldElementClass = field.getType();
try { try {
OdinDto someInstance = (OdinDto) ((Class) (fieldElementClass)).getDeclaredConstructor().newInstance(); OdinDto someInstance = (OdinDto) ((Class) (fieldElementClass)).newInstance();
this.path = someInstance.getControllerPath(); this.path = someInstance.getControllerPath();
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { } catch (IllegalAccessException | InstantiationException e) {
throw new OdinException(String.format("Can't create new instance, check default constructor of %s", throw new OdinException(String.format("Can't create new instance, check default constructor of %s",
fieldElementClass.getTypeName())); fieldElementClass.getTypeName()));
} }

View File

@ -1,10 +1,10 @@
package ru.ulstu.odin.model; package ru.ulstu.odin.model;
import jakarta.validation.constraints.Email; import org.hibernate.validator.constraints.Email;
import jakarta.validation.constraints.Size;
import ru.ulstu.odin.model.annotation.OdinString; import ru.ulstu.odin.model.annotation.OdinString;
import ru.ulstu.odin.model.annotation.OdinString.OdinStringType; import ru.ulstu.odin.model.annotation.OdinString.OdinStringType;
import javax.validation.constraints.Size;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import static ru.ulstu.odin.model.annotation.OdinString.OdinStringType.EMAIL; import static ru.ulstu.odin.model.annotation.OdinString.OdinStringType.EMAIL;

View File

@ -0,0 +1,4 @@
package ru.ulstu.odinexample.controller;
public class OdinExampleController {
}

View File

@ -0,0 +1,4 @@
package ru.ulstu.odinexample.model;
public class OdinExampleDto {
}

View File

@ -0,0 +1,103 @@
package ru.ulstu.odinexample.model;
import ru.ulstu.core.util.DateUtils;
import ru.ulstu.odin.model.annotation.OdinCaption;
import ru.ulstu.odin.model.annotation.OdinDate;
import ru.ulstu.odin.model.annotation.OdinNumeric;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
public class OdinExampleListDto {
@OdinCaption("instant")
@OdinDate(type = OdinDate.OdinDateType.DATETIME)
private Instant instant;
@OdinCaption("date")
private Date date;
@OdinCaption("localdate")
private LocalDate localDate;
@OdinCaption("localtime")
@OdinDate(type = OdinDate.OdinDateType.TIME)
private LocalTime localTime;
@OdinCaption("localdatetime")
@OdinDate(type = OdinDate.OdinDateType.DATETIME)
private LocalDateTime localDateTime;
@OdinCaption("int")
private int intval;
@OdinCaption("int+settings")
@OdinNumeric(precision = 5, scale = 2)
private int intvalset;
@OdinCaption("float")
private float floatval;
@OdinCaption("double")
private double aDouble;
@OdinCaption("double+set")
@OdinNumeric(precision = 5, scale = 3)
private double aDoubles;
@OdinCaption("int+positive")
@OdinNumeric(positiveOnly = true, scale = 2)
private int invalpos;
public OdinExampleListDto() {
this.instant = Instant.now();
this.date = new Date();
this.localDate = LocalDate.now();
this.localTime = LocalTime.now();
this.localDateTime = LocalDateTime.now();
intval = -134;
intvalset = 1343423232;
floatval = 2323.44F;
aDouble = -232323.43434;
aDoubles = 0.456456456;
invalpos = -23232323;
}
public Date getInstant() {
return DateUtils.instantToDate(instant);
}
public Date getDate() {
return date;
}
public Date getLocalDate() {
return DateUtils.localDateToDate(localDate);
}
public Date getLocalTime() {
return DateUtils.localTimeToDate(localTime);
}
public Date getLocalDateTime() {
return DateUtils.localDateTimeToDate(localDateTime);
}
public int getIntval() {
return intval;
}
public int getIntvalset() {
return intvalset;
}
public float getFloatval() {
return floatval;
}
public double getaDouble() {
return aDouble;
}
public double getaDoubles() {
return aDoubles;
}
public int getInvalpos() {
return invalpos;
}
}

View File

@ -0,0 +1,4 @@
package ru.ulstu.odinexample.service;
public class OdinExampleService {
}

View File

@ -1,74 +1,59 @@
package ru.ulstu.paper.controller; package ru.ulstu.paper.controller;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors; import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping; 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.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
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 ru.ulstu.conference.service.ConferenceService; import ru.ulstu.deadline.model.DeadlineDto;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.paper.model.AutoCompleteData;
import ru.ulstu.paper.model.Paper; import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.model.PaperDto; import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.paper.model.PaperListDto; import ru.ulstu.paper.model.PaperFilterDto;
import ru.ulstu.paper.service.LatexService;
import ru.ulstu.paper.service.PaperService; import ru.ulstu.paper.service.PaperService;
import ru.ulstu.user.model.User; import ru.ulstu.user.model.User;
import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.springframework.util.StringUtils.isEmpty;
@Controller() @Controller()
@RequestMapping(value = "/papers") @RequestMapping(value = "/papers")
@Hidden
public class PaperController { public class PaperController {
private final PaperService paperService; private final PaperService paperService;
private final ConferenceService conferenceService;
private final LatexService latexService;
public PaperController(PaperService paperService, public PaperController(PaperService paperService) {
ConferenceService conferenceService,
LatexService latexService) {
this.paperService = paperService; this.paperService = paperService;
this.conferenceService = conferenceService;
this.latexService = latexService;
} }
@GetMapping("/papers") @GetMapping("/papers")
public void getPapers(ModelMap modelMap) { public void getPapers(ModelMap modelMap) {
modelMap.put("filteredPapers", new PaperListDto(paperService.findAllDto(), null, null)); modelMap.put("filteredPapers", new PaperFilterDto(paperService.findAllDto(), null, null));
} }
@PostMapping("/papers") @PostMapping("/papers")
public void listPapers(@Valid PaperListDto paperListDto, ModelMap modelMap) { public void filterPapers(@Valid PaperFilterDto paperFilterDto, ModelMap modelMap) {
if (paperListDto.getPaperDeleteId() != null) { modelMap.put("filteredPapers", new PaperFilterDto(paperService.filter(paperFilterDto),
if (conferenceService.isAttachedToConference(paperListDto.getPaperDeleteId())) { paperFilterDto.getFilterAuthorId(),
modelMap.put("flashMessage", "Статью нельзя удалить, она прикреплена к конференции"); paperFilterDto.getYear()));
} else {
paperService.delete(paperListDto.getPaperDeleteId());
}
}
modelMap.put("filteredPapers", new PaperListDto(paperService.filter(paperListDto),
paperListDto.getFilterAuthorId(),
paperListDto.getYear()));
} }
@GetMapping("/dashboard") @GetMapping("/dashboard")
public void getDashboard(ModelMap modelMap) { public void getDashboard(ModelMap modelMap) {
modelMap.put("papers", paperService.findAllActiveDto()); modelMap.put("papers", paperService.findAllDto());
} }
@GetMapping("/paper") @GetMapping("/paper")
public void getPaper(ModelMap modelMap, @RequestParam(value = "id") Integer id) { public void getPapers(ModelMap modelMap, @RequestParam(value = "id") Integer id) {
if (id != null && id > 0) { if (id != null && id > 0) {
modelMap.put("paperDto", paperService.findOneDto(id)); modelMap.put("paperDto", paperService.findOneDto(id));
} else { } else {
@ -95,20 +80,21 @@ public class PaperController {
if (errors.hasErrors()) { if (errors.hasErrors()) {
return "/papers/paper"; return "/papers/paper";
} }
paperDto.getDeadlines().add(new Deadline()); paperDto.getDeadlines().add(new DeadlineDto());
return "/papers/paper"; return "/papers/paper";
} }
@GetMapping("/delete/{paper-id}")
public String delete(@PathVariable("paper-id") Integer paperId) throws IOException {
paperService.delete(paperId);
return "redirect:/papers/papers";
}
@ModelAttribute("allStatuses") @ModelAttribute("allStatuses")
public List<Paper.PaperStatus> getPaperStatuses() { public List<Paper.PaperStatus> getPaperStatuses() {
return paperService.getPaperStatuses(); return paperService.getPaperStatuses();
} }
@ModelAttribute("allTypes")
public List<Paper.PaperType> getPaperTypes() {
return paperService.getPaperTypes();
}
@ModelAttribute("allAuthors") @ModelAttribute("allAuthors")
public List<User> getAllAuthors() { public List<User> getAllAuthors() {
return paperService.getPaperAuthors(); return paperService.getPaperAuthors();
@ -123,14 +109,9 @@ public class PaperController {
return years; return years;
} }
@ModelAttribute("autocompleteData")
public AutoCompleteData getAutocompleteData() {
return paperService.getAutoCompleteData();
}
private void filterEmptyDeadlines(PaperDto paperDto) { private void filterEmptyDeadlines(PaperDto paperDto) {
paperDto.setDeadlines(paperDto.getDeadlines().stream() paperDto.setDeadlines(paperDto.getDeadlines().stream()
.filter(dto -> dto.getDate() != null || !dto.getDescription().isEmpty()) .filter(dto -> dto.getDate() != null || !isEmpty(dto.getDescription()))
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
} }

View File

@ -1,6 +1,5 @@
package ru.ulstu.paper.controller; package ru.ulstu.paper.controller;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -8,15 +7,14 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
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.RestController; import org.springframework.web.bind.annotation.RestController;
import ru.ulstu.configuration.Constants; import ru.ulstu.configuration.Constants;
import ru.ulstu.core.model.response.Response; import ru.ulstu.core.model.response.Response;
import ru.ulstu.paper.model.PaperDto; import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.paper.model.PaperListDto; import ru.ulstu.paper.model.PaperFilterDto;
import ru.ulstu.paper.model.ReferenceDto;
import ru.ulstu.paper.service.PaperService; import ru.ulstu.paper.service.PaperService;
import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@ -40,7 +38,7 @@ public class PaperRestController {
@GetMapping("/{paper-id}") @GetMapping("/{paper-id}")
public Response<PaperDto> getPaper(@PathVariable("paper-id") Integer paperId){ public Response<PaperDto> getPaper(@PathVariable("paper-id") Integer paperId){
return new Response<>(paperService.findById(paperId)); return new Response(paperService.findById(paperId));
} }
@PostMapping @PostMapping
@ -56,26 +54,11 @@ public class PaperRestController {
@DeleteMapping("/{paper-id}") @DeleteMapping("/{paper-id}")
public Response<Boolean> delete(@PathVariable("paper-id") Integer paperId) throws IOException { public Response<Boolean> delete(@PathVariable("paper-id") Integer paperId) throws IOException {
paperService.delete(paperId); paperService.delete(paperId);
return new Response<>(Boolean.TRUE); return new Response<>(true);
} }
@PostMapping("/filter") @PostMapping("/filter")
public Response<List<PaperDto>> filter(@RequestBody @Valid PaperListDto paperListDto) throws IOException { public Response<List<PaperDto>> filter(@RequestBody @Valid PaperFilterDto paperFilterDto) throws IOException {
return new Response<>(paperService.filter(paperListDto)); return new Response<>(paperService.filter(paperFilterDto));
}
@GetMapping("formatted-list")
public Response<List<String>> getFormattedPaperList() {
return new Response<>(paperService.getFormattedPaperList());
}
@PostMapping("/getFormattedReference")
public Response<String> getFormattedReference(@RequestBody @Valid ReferenceDto referenceDto) {
return new Response<>(paperService.getFormattedReference(referenceDto));
}
@PostMapping(value = "/ping")
public void ping(@RequestParam("paperId") int paperId) throws IOException {
paperService.ping(paperId);
} }
} }

View File

@ -1,43 +0,0 @@
package ru.ulstu.paper.model;
import java.util.ArrayList;
import java.util.List;
public class AutoCompleteData {
private List<String> authors = new ArrayList<>();
private List<String> publicationTitles = new ArrayList<>();
private List<String> publishers = new ArrayList<>();
private List<String> journalOrCollectionTitles = new ArrayList<>();
public List<String> getAuthors() {
return authors;
}
public void setAuthors(List<String> authors) {
this.authors = authors;
}
public List<String> getPublicationTitles() {
return publicationTitles;
}
public void setPublicationTitles(List<String> publicationTitles) {
this.publicationTitles = publicationTitles;
}
public List<String> getPublishers() {
return publishers;
}
public void setPublishers(List<String> publishers) {
this.publishers = publishers;
}
public List<String> getJournalOrCollectionTitles() {
return journalOrCollectionTitles;
}
public void setJournalOrCollectionTitles(List<String> journalOrCollectionTitles) {
this.journalOrCollectionTitles = journalOrCollectionTitles;
}
}

View File

@ -1,87 +1,56 @@
package ru.ulstu.paper.model; package ru.ulstu.paper.model;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderBy;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import jakarta.validation.constraints.NotBlank;
import org.hibernate.annotations.Fetch; import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.FetchMode;
import org.springframework.format.annotation.DateTimeFormat; import org.hibernate.validator.constraints.NotBlank;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.core.model.EventSource; import ru.ulstu.core.model.UserContainer;
import ru.ulstu.core.model.UserActivity;
import ru.ulstu.deadline.model.Deadline; import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.file.model.FileData; import ru.ulstu.file.model.FileData;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.timeline.model.Event;
import ru.ulstu.user.model.User; import ru.ulstu.user.model.User;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@Entity @Entity
@DiscriminatorValue("PAPER") public class Paper extends BaseEntity implements UserContainer {
public class Paper extends BaseEntity implements UserActivity, EventSource {
public enum PaperStatus { public enum PaperStatus {
ATTENTION("Обратить внимание", "text-warning"), ATTENTION("Обратить внимание"),
ON_PREPARATION("На подготовке", "text-primary"), ON_PREPARATION("На подготовке"),
ON_REVIEW("Отправлена на проверку", "text-review"), ON_REVIEW("Отправлена на проверку"),
ACCEPTED("Принята", "text-accepted"), ACCEPTED("Принята"),
NOT_ACCEPTED("Не принята", "text-not-accepted"), NOT_ACCEPTED("Не принята"),
COMPLETED("Завершена (опубликована)", "text-success"), COMPLETED("Завершена (опубликована)"),
DRAFT("Черновик", "text-draft"), DRAFT("Черновик"),
FAILED("Провалены сроки", "text-failed"); FAILED("Провалены сроки");
private final String statusName; private String statusName;
private final String elementClass;
PaperStatus(String name, String elementClass) { PaperStatus(String name) {
this.statusName = name; this.statusName = name;
this.elementClass = elementClass;
} }
public String getStatusName() { public String getStatusName() {
return statusName; return statusName;
} }
public String getElementClass() {
return elementClass;
}
}
public enum PaperType {
OTHER("Прочая публикация"),
VAK("ВАК"),
SCOPUS("Scopus"),
WEB_OF_SCIENCE("Web Of Science");
private final String typeName;
PaperType(String name) {
this.typeName = name;
}
public String getTypeName() {
return typeName;
}
} }
@NotBlank @NotBlank
@ -90,20 +59,15 @@ public class Paper extends BaseEntity implements UserActivity, EventSource {
@Enumerated(value = EnumType.STRING) @Enumerated(value = EnumType.STRING)
private PaperStatus status = PaperStatus.DRAFT; private PaperStatus status = PaperStatus.DRAFT;
@Enumerated(value = EnumType.STRING)
private PaperType type = PaperType.OTHER;
@Column(name = "create_date") @Column(name = "create_date")
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSXXX")
private Date createDate = new Date(); private Date createDate = new Date();
@Column(name = "update_date") @Column(name = "update_date")
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSXXX")
private Date updateDate = new Date(); private Date updateDate = new Date();
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "paper_id", unique = true) @JoinColumn(name = "paper_id", unique = true)
@Fetch(FetchMode.SUBSELECT) @Fetch(FetchMode.SUBSELECT)
@OrderBy("date") @OrderBy("date")
@ -111,32 +75,14 @@ public class Paper extends BaseEntity implements UserActivity, EventSource {
private String comment; private String comment;
private String url;
private Boolean locked = false; private Boolean locked = false;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @ManyToOne
@JoinColumn(name = "paper_id") @JoinColumn(name = "file_id")
private List<Event> events = new ArrayList<>(); private FileData fileData;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "paper_id", unique = true)
@Fetch(FetchMode.SUBSELECT)
private List<FileData> files = new ArrayList<>();
@ManyToMany(fetch = FetchType.EAGER) @ManyToMany(fetch = FetchType.EAGER)
private Set<User> authors = new HashSet<>(); private Set<User> authors = new HashSet<>();
@ManyToOne()
@JoinColumn(name = "conference_id")
private Conference conference;
@ManyToMany(mappedBy = "papers")
private List<Grant> grants;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "paper_id", unique = true)
@Fetch(FetchMode.SUBSELECT)
private List<Reference> references = new ArrayList<>();
public PaperStatus getStatus() { public PaperStatus getStatus() {
return status; return status;
@ -146,14 +92,6 @@ public class Paper extends BaseEntity implements UserActivity, EventSource {
this.status = status; this.status = status;
} }
public PaperType getType() {
return type;
}
public void setType(PaperType type) {
this.type = type;
}
public Date getCreateDate() { public Date getCreateDate() {
return createDate; return createDate;
} }
@ -194,28 +132,18 @@ public class Paper extends BaseEntity implements UserActivity, EventSource {
this.locked = locked; this.locked = locked;
} }
public List<FileData> getFiles() { public FileData getFileData() {
return files; return fileData;
} }
public void setFiles(List<FileData> files) { public void setFileData(FileData fileData) {
this.files = files; this.fileData = fileData;
} }
public String getTitle() { public String getTitle() {
return title; return title;
} }
@Override
public List<User> getRecipients() {
return new ArrayList<>(authors);
}
@Override
public void addObjectToEvent(Event event) {
event.setPaper(this);
}
public void setTitle(String title) { public void setTitle(String title) {
this.title = title; this.title = title;
} }
@ -228,51 +156,11 @@ public class Paper extends BaseEntity implements UserActivity, EventSource {
this.authors = authors; this.authors = authors;
} }
public List<Event> getEvents() {
return events;
}
public void setEvents(List<Event> events) {
this.events = events;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Conference getConference() {
return conference;
}
public void setConference(Conference conference) {
this.conference = conference;
}
public List<Grant> getGrants() {
return grants;
}
public void setGrants(List<Grant> grants) {
this.grants = grants;
}
@Override @Override
public Set<User> getActivityUsers() { public Set<User> getUsers() {
return getAuthors(); return getAuthors();
} }
public List<Reference> getReferences() {
return references;
}
public void setReferences(List<Reference> references) {
this.references = references;
}
public Optional<Deadline> getNextDeadline() { public Optional<Deadline> getNextDeadline() {
return deadlines return deadlines
.stream() .stream()
@ -281,44 +169,4 @@ public class Paper extends BaseEntity implements UserActivity, EventSource {
.filter(d -> d.getDate().after(new Date())) .filter(d -> d.getDate().after(new Date()))
.findFirst(); .findFirst();
} }
public boolean lastDeadlineFailed() {
return !deadlines
.stream()
.filter(deadline -> deadline.getDate() != null)
.filter(d -> d.getDate().after(new Date()))
.findAny()
.isPresent();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
Paper paper = (Paper) o;
return Objects.equals(title, paper.title) &&
status == paper.status &&
type == paper.type &&
Objects.equals(deadlines, paper.deadlines) &&
Objects.equals(comment, paper.comment) &&
Objects.equals(url, paper.url) &&
Objects.equals(locked, paper.locked) &&
Objects.equals(events, paper.events) &&
Objects.equals(files, paper.files) &&
Objects.equals(authors, paper.authors) &&
Objects.equals(conference, paper.conference) &&
Objects.equals(grants, paper.grants);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), title, status, type, createDate, updateDate, deadlines, comment, url, locked, events, files, authors, conference, grants);
}
} }

View File

@ -2,15 +2,12 @@ package ru.ulstu.paper.model;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.format.annotation.DateTimeFormat; import org.hibernate.validator.constraints.NotEmpty;
import ru.ulstu.core.model.BaseEntity; import ru.ulstu.deadline.model.DeadlineDto;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.file.model.FileDataDto;
import ru.ulstu.user.model.UserDto; import ru.ulstu.user.model.UserDto;
import javax.validation.constraints.Size;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -27,77 +24,66 @@ public class PaperDto {
@Size(min = 3, max = 254) @Size(min = 3, max = 254)
private String title; private String title;
private Paper.PaperStatus status; private Paper.PaperStatus status;
private Paper.PaperType type;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSXXX")
private Date createDate; private Date createDate;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSXXX")
private Date updateDate; private Date updateDate;
@NotEmpty @NotEmpty
private List<Deadline> deadlines = new ArrayList<>(); private List<DeadlineDto> deadlines = new ArrayList<>();
private String comment; private String comment;
private String url;
private Boolean locked; private Boolean locked;
private List<FileDataDto> files = new ArrayList<>(); private String tmpFileName;
private Integer fileId;
private String fileName;
private Date fileCreateDate;
private Set<Integer> authorIds; private Set<Integer> authorIds;
private Set<UserDto> authors; private Set<UserDto> authors;
private Integer filterAuthorId; private Integer filterAuthorId;
private String latexText;
private List<ReferenceDto> references = new ArrayList<>();
private ReferenceDto.FormatStandard formatStandard = ReferenceDto.FormatStandard.GOST;
public PaperDto() { public PaperDto() {
deadlines.add(new Deadline()); deadlines.add(new DeadlineDto());
} }
@JsonCreator @JsonCreator
public PaperDto(@JsonProperty("id") Integer id, public PaperDto(@JsonProperty("id") Integer id,
@JsonProperty("title") String title, @JsonProperty("title") String title,
@JsonProperty("status") Paper.PaperStatus status, @JsonProperty("status") Paper.PaperStatus status,
@JsonProperty("type") Paper.PaperType type,
@JsonProperty("createDate") Date createDate, @JsonProperty("createDate") Date createDate,
@JsonProperty("updateDate") Date updateDate, @JsonProperty("updateDate") Date updateDate,
@JsonProperty("deadlines") List<Deadline> deadlines, @JsonProperty("deadlines") List<DeadlineDto> deadlines,
@JsonProperty("comment") String comment, @JsonProperty("comment") String comment,
@JsonProperty("latex_text") String latexText,
@JsonProperty("url") String url,
@JsonProperty("locked") Boolean locked, @JsonProperty("locked") Boolean locked,
@JsonProperty("files") List<FileDataDto> files, @JsonProperty("tmpFileName") String tmpFileName,
@JsonProperty("authorIds") Set<Integer> authorIds, @JsonProperty("authorIds") Set<Integer> authorIds,
@JsonProperty("authors") Set<UserDto> authors, @JsonProperty("authors") Set<UserDto> authors) {
@JsonProperty("references") List<ReferenceDto> references,
@JsonProperty("formatStandard") ReferenceDto.FormatStandard formatStandard) {
this.id = id; this.id = id;
this.title = title; this.title = title;
this.status = status; this.status = status;
this.type = type;
this.createDate = createDate; this.createDate = createDate;
this.updateDate = updateDate; this.updateDate = updateDate;
this.deadlines = deadlines; this.deadlines = deadlines;
this.comment = comment; this.comment = comment;
this.url = url;
this.latexText = latexText;
this.locked = locked; this.locked = locked;
this.files = files; this.tmpFileName = tmpFileName;
this.fileId = null;
this.fileName = null;
this.fileCreateDate = null;
this.authors = authors; this.authors = authors;
this.references = references;
this.formatStandard = formatStandard;
} }
public PaperDto(Paper paper) { public PaperDto(Paper paper) {
this.id = paper.getId(); this.id = paper.getId();
this.title = paper.getTitle(); this.title = paper.getTitle();
this.status = paper.getStatus(); this.status = paper.getStatus();
this.type = paper.getType();
this.createDate = paper.getCreateDate(); this.createDate = paper.getCreateDate();
this.updateDate = paper.getUpdateDate(); this.updateDate = paper.getUpdateDate();
this.deadlines = paper.getDeadlines(); this.deadlines = convert(paper.getDeadlines(), DeadlineDto::new);
this.comment = paper.getComment(); this.comment = paper.getComment();
this.url = paper.getUrl();
this.locked = paper.getLocked(); this.locked = paper.getLocked();
this.files = convert(paper.getFiles(), FileDataDto::new); this.tmpFileName = null;
this.authorIds = convert(paper.getAuthors(), BaseEntity::getId); this.fileId = paper.getFileData() == null ? null : paper.getFileData().getId();
this.fileName = paper.getFileData() == null ? null : paper.getFileData().getName();
this.fileCreateDate = paper.getFileData() == null ? null : paper.getFileData().getCreateDate();
this.authorIds = convert(paper.getAuthors(), user -> user.getId());
this.authors = convert(paper.getAuthors(), UserDto::new); this.authors = convert(paper.getAuthors(), UserDto::new);
this.references = convert(paper.getReferences(), ReferenceDto::new);
} }
public Integer getId() { public Integer getId() {
@ -124,14 +110,6 @@ public class PaperDto {
this.status = status; this.status = status;
} }
public Paper.PaperType getType() {
return type;
}
public void setType(Paper.PaperType type) {
this.type = type;
}
public Date getCreateDate() { public Date getCreateDate() {
return createDate; return createDate;
} }
@ -148,11 +126,11 @@ public class PaperDto {
this.updateDate = updateDate; this.updateDate = updateDate;
} }
public List<Deadline> getDeadlines() { public List<DeadlineDto> getDeadlines() {
return deadlines; return deadlines;
} }
public void setDeadlines(List<Deadline> deadlines) { public void setDeadlines(List<DeadlineDto> deadlines) {
this.deadlines = deadlines; this.deadlines = deadlines;
} }
@ -172,12 +150,36 @@ public class PaperDto {
this.locked = locked; this.locked = locked;
} }
public List<FileDataDto> getFiles() { public String getTmpFileName() {
return files; return tmpFileName;
} }
public void setFiles(List<FileDataDto> files) { public void setTmpFileName(String tmpFileName) {
this.files = files; this.tmpFileName = tmpFileName;
}
public Integer getFileId() {
return fileId;
}
public void setFileId(Integer fileId) {
this.fileId = fileId;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public Date getFileCreateDate() {
return fileCreateDate;
}
public void setFileCreateDate(Date fileCreateDate) {
this.fileCreateDate = fileCreateDate;
} }
public Set<UserDto> getAuthors() { public Set<UserDto> getAuthors() {
@ -196,26 +198,10 @@ public class PaperDto {
this.authorIds = authorIds; this.authorIds = authorIds;
} }
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getLatexText() {
return latexText;
}
public void setLatexText(String latexText) {
this.latexText = latexText;
}
public String getAuthorsString() { public String getAuthorsString() {
return StringUtils.abbreviate(authors return StringUtils.abbreviate(authors
.stream() .stream()
.map(UserDto::getLastName) .map(author -> author.getLastName())
.collect(Collectors.joining(", ")), MAX_AUTHORS_LENGTH); .collect(Collectors.joining(", ")), MAX_AUTHORS_LENGTH);
} }
@ -226,20 +212,4 @@ public class PaperDto {
public void setFilterAuthorId(Integer filterAuthorId) { public void setFilterAuthorId(Integer filterAuthorId) {
this.filterAuthorId = filterAuthorId; this.filterAuthorId = filterAuthorId;
} }
public List<ReferenceDto> getReferences() {
return references;
}
public void setReferences(List<ReferenceDto> references) {
this.references = references;
}
public ReferenceDto.FormatStandard getFormatStandard() {
return formatStandard;
}
public void setFormatStandard(ReferenceDto.FormatStandard formatStandard) {
this.formatStandard = formatStandard;
}
} }

View File

@ -2,16 +2,15 @@ package ru.ulstu.paper.model;
import java.util.List; import java.util.List;
public class PaperListDto { public class PaperFilterDto {
private List<PaperDto> papers; private List<PaperDto> papers;
private Integer filterAuthorId; private Integer filterAuthorId;
private Integer paperDeleteId;
private Integer year; private Integer year;
public PaperListDto() { public PaperFilterDto() {
} }
public PaperListDto(List<PaperDto> paperDtos, Integer filterAuthorId, Integer year) { public PaperFilterDto(List<PaperDto> paperDtos, Integer filterAuthorId, Integer year) {
this.papers = paperDtos; this.papers = paperDtos;
this.filterAuthorId = filterAuthorId; this.filterAuthorId = filterAuthorId;
this.year = year; this.year = year;
@ -40,12 +39,4 @@ public class PaperListDto {
public void setYear(Integer year) { public void setYear(Integer year) {
this.year = year; this.year = year;
} }
public Integer getPaperDeleteId() {
return paperDeleteId;
}
public void setPaperDeleteId(Integer paperDeleteId) {
this.paperDeleteId = paperDeleteId;
}
} }

View File

@ -1,87 +0,0 @@
package ru.ulstu.paper.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import ru.ulstu.core.model.BaseEntity;
@Entity
public class Reference extends BaseEntity {
private String authors;
@Column(name = "publication_title")
private String publicationTitle;
@Column(name = "publication_year")
private Integer publicationYear;
private String publisher;
private String pages;
@Column(name = "journal_or_collection_title")
private String journalOrCollectionTitle;
@Enumerated(value = EnumType.STRING)
@Column(name = "reference_type")
private ReferenceDto.ReferenceType referenceType = ReferenceDto.ReferenceType.ARTICLE;
public String getAuthors() {
return authors;
}
public void setAuthors(String authors) {
this.authors = authors;
}
public String getPublicationTitle() {
return publicationTitle;
}
public void setPublicationTitle(String publicationTitle) {
this.publicationTitle = publicationTitle;
}
public Integer getPublicationYear() {
return publicationYear;
}
public void setPublicationYear(Integer publicationYear) {
this.publicationYear = publicationYear;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getPages() {
return pages;
}
public void setPages(String pages) {
this.pages = pages;
}
public String getJournalOrCollectionTitle() {
return journalOrCollectionTitle;
}
public void setJournalOrCollectionTitle(String journalOrCollectionTitle) {
this.journalOrCollectionTitle = journalOrCollectionTitle;
}
public ReferenceDto.ReferenceType getReferenceType() {
return referenceType;
}
public void setReferenceType(ReferenceDto.ReferenceType referenceType) {
this.referenceType = referenceType;
}
}

View File

@ -1,166 +0,0 @@
package ru.ulstu.paper.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class ReferenceDto {
public enum ReferenceType {
ARTICLE("Статья"),
BOOK("Книга");
private final String typeName;
ReferenceType(String name) {
this.typeName = name;
}
public String getTypeName() {
return typeName;
}
}
public enum FormatStandard {
GOST("ГОСТ"),
SPRINGER("Springer");
private final String standardName;
FormatStandard(String name) {
this.standardName = name;
}
public String getStandardName() {
return standardName;
}
}
private Integer id;
private String authors;
private String publicationTitle;
private Integer publicationYear;
private String publisher;
private String pages;
private String journalOrCollectionTitle;
private ReferenceType referenceType;
private FormatStandard formatStandard;
private boolean deleted;
@JsonCreator
public ReferenceDto(
@JsonProperty("id") Integer id,
@JsonProperty("authors") String authors,
@JsonProperty("publicationTitle") String publicationTitle,
@JsonProperty("publicationYear") Integer publicationYear,
@JsonProperty("publisher") String publisher,
@JsonProperty("pages") String pages,
@JsonProperty("journalOrCollectionTitle") String journalOrCollectionTitle,
@JsonProperty("referenceType") ReferenceType referenceType,
@JsonProperty("formatStandard") FormatStandard formatStandard,
@JsonProperty("isDeleted") boolean deleted) {
this.id = id;
this.authors = authors;
this.publicationTitle = publicationTitle;
this.publicationYear = publicationYear;
this.publisher = publisher;
this.pages = pages;
this.journalOrCollectionTitle = journalOrCollectionTitle;
this.referenceType = referenceType;
this.formatStandard = formatStandard;
this.deleted = deleted;
}
public ReferenceDto(Reference reference) {
this.id = reference.getId();
this.authors = reference.getAuthors();
this.publicationTitle = reference.getPublicationTitle();
this.publicationYear = reference.getPublicationYear();
this.publisher = reference.getPublisher();
this.pages = reference.getPages();
this.journalOrCollectionTitle = reference.getJournalOrCollectionTitle();
this.referenceType = reference.getReferenceType();
}
public ReferenceDto() {
referenceType = ReferenceType.ARTICLE;
}
public String getAuthors() {
return authors;
}
public void setAuthors(String authors) {
this.authors = authors;
}
public String getPublicationTitle() {
return publicationTitle;
}
public void setPublicationTitle(String publicationTitle) {
this.publicationTitle = publicationTitle;
}
public Integer getPublicationYear() {
return publicationYear;
}
public void setPublicationYear(Integer publicationYear) {
this.publicationYear = publicationYear;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getPages() {
return pages;
}
public void setPages(String pages) {
this.pages = pages;
}
public String getJournalOrCollectionTitle() {
return journalOrCollectionTitle;
}
public void setJournalOrCollectionTitle(String journalOrCollectionTitle) {
this.journalOrCollectionTitle = journalOrCollectionTitle;
}
public ReferenceType getReferenceType() {
return referenceType;
}
public void setReferenceType(ReferenceType referenceType) {
this.referenceType = referenceType;
}
public FormatStandard getFormatStandard() {
return formatStandard;
}
public void setFormatStandard(FormatStandard formatStandard) {
this.formatStandard = formatStandard;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public boolean getDeleted() {
return deleted;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
}

View File

@ -12,16 +12,4 @@ public interface PaperRepository extends JpaRepository<Paper, Integer> {
@Query("SELECT p FROM Paper p WHERE (:author IS NULL OR :author MEMBER OF p.authors) AND (YEAR(p.createDate) = :year OR :year IS NULL)") @Query("SELECT p FROM Paper p WHERE (:author IS NULL OR :author MEMBER OF p.authors) AND (YEAR(p.createDate) = :year OR :year IS NULL)")
List<Paper> filter(@Param("author") User author, @Param("year") Integer year); List<Paper> filter(@Param("author") User author, @Param("year") Integer year);
List<Paper> findByIdNotIn(List<Integer> paperIds);
List<Paper> findAllByIdIn(List<Integer> paperIds);
List<Paper> findByTypeAndStatus(Paper.PaperType type, Paper.PaperStatus status);
List<Paper> findByStatusNot(Paper.PaperStatus status);
List<Paper> findByConferenceIsNullAndStatusNot(Paper.PaperStatus status);
List<Paper> findByIdNotInAndConferenceIsNullAndStatusNot(List<Integer> paperIds, Paper.PaperStatus status);
} }

View File

@ -1,23 +0,0 @@
package ru.ulstu.paper.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import ru.ulstu.paper.model.Reference;
import java.util.List;
public interface ReferenceRepository extends JpaRepository<Reference, Integer> {
void deleteById(Integer id);
@Query("SELECT DISTINCT r.authors FROM Reference r")
List<String> findDistinctAuthors();
@Query("SELECT DISTINCT r.publicationTitle FROM Reference r")
List<String> findDistinctPublicationTitles();
@Query("SELECT DISTINCT r.publisher FROM Reference r")
List<String> findDistinctPublishers();
@Query("SELECT DISTINCT r.journalOrCollectionTitle FROM Reference r where r.journalOrCollectionTitle <> ''")
List<String> findDistinctJournalOrCollectionTitles();
}

View File

@ -1,77 +0,0 @@
package ru.ulstu.paper.service;
import org.springframework.stereotype.Service;
import ru.ulstu.file.service.FileService;
import ru.ulstu.paper.model.PaperDto;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
@Service
public class LatexService {
private static final String PDF_LATEX_ERROR = "Errors occurred while executing pdfLaTeX.";
private static final String BIBTEX_ERROR = "Errors occurred while executing bibtex.";
private String errorMessage;
private File pdfFile;
private final FileService fileService;
public LatexService(FileService fileService) {
this.fileService = fileService;
}
public byte[] generatePdfFromLatexFile(PaperDto paper) throws IOException, InterruptedException {
fileService.createLatexAttachs(paper);
File tex = fileService.createLatexFile(paper);
if (!generate(paper.getTitle(), tex.getParentFile())) {
throw new IOException(errorMessage);
}
return Files.readAllBytes(pdfFile.toPath());
}
private int startProcess(String[] args, File dir, String message) throws IOException, InterruptedException {
ProcessBuilder processBuilder = new ProcessBuilder(args);
processBuilder.redirectErrorStream(true);
processBuilder.directory(dir);
Process process = processBuilder.start();
InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
try (BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
String line = bufferedReader.readLine();
while (line != null) {
line = bufferedReader.readLine();
}
}
int exitCode = process.waitFor();
if (exitCode != 0) {
errorMessage = message + " Exit value of the process: " + exitCode;
}
return exitCode;
}
private boolean generate(String filename, File dir) throws IOException, InterruptedException {
startProcess(new String[]{"pdflatex", filename, "--interaction=nonstopmode"}, dir, PDF_LATEX_ERROR);
startProcess(new String[]{"bibtex", filename}, dir, BIBTEX_ERROR);
if (startProcess(new String[]{"pdflatex", filename, "--interaction=nonstopmode"}, dir, PDF_LATEX_ERROR) != 0) {
return false;
}
return checkPdf(filename, dir);
}
private boolean checkPdf(String filename, File dir) {
pdfFile = new File(dir.getAbsolutePath() + File.separator + filename + ".pdf");
if (pdfFile.isFile()) {
return true;
} else {
errorMessage = "The pdf file could not be created.";
return false;
}
}
}

View File

@ -1,5 +1,6 @@
package ru.ulstu.paper.service; package ru.ulstu.paper.service;
import com.google.common.collect.ImmutableMap;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.ulstu.core.util.DateUtils; import ru.ulstu.core.util.DateUtils;
import ru.ulstu.paper.model.Paper; import ru.ulstu.paper.model.Paper;
@ -45,22 +46,22 @@ public class PaperNotificationService {
} }
private void sendMessageDeadline(Paper paper) { private void sendMessageDeadline(Paper paper) {
Map<String, Object> variables = Map.of("paper", paper); Map<String, Object> variables = ImmutableMap.of("paper", paper);
sendForAllAuhtors(variables, paper, TEMPLATE_DEADLINE, TITLE_DEADLINE); sendForAllAuhtors(variables, paper, TEMPLATE_DEADLINE, TITLE_DEADLINE);
} }
public void sendCreateNotification(Paper paper) { public void sendCreateNotification(Paper paper) {
Map<String, Object> variables = Map.of("paper", paper); Map<String, Object> variables = ImmutableMap.of("paper", paper);
sendForAllAuhtors(variables, paper, TEMPLATE_CREATE, TITLE_CREATE); sendForAllAuhtors(variables, paper, TEMPLATE_CREATE, TITLE_CREATE);
} }
public void statusChangeNotification(Paper paper, Paper.PaperStatus oldStatus) { public void statusChangeNotification(Paper paper, Paper.PaperStatus oldStatus) {
Map<String, Object> variables = Map.of("paper", paper, "oldStatus", oldStatus); Map<String, Object> variables = ImmutableMap.of("paper", paper, "oldStatus", oldStatus);
sendForAllAuhtors(variables, paper, TEMPLATE_STATUS_CHANGED, TITLE_STATUS_CHANGED); sendForAllAuhtors(variables, paper, TEMPLATE_STATUS_CHANGED, TITLE_STATUS_CHANGED);
} }
public void sendFailedNotification(Paper paper, Paper.PaperStatus oldStatus) { public void sendFailedNotification(Paper paper, Paper.PaperStatus oldStatus) {
Map<String, Object> variables = Map.of("paper", paper, "oldStatus", oldStatus); Map<String, Object> variables = ImmutableMap.of("paper", paper, "oldStatus", oldStatus);
sendForAllAuhtors(variables, paper, TEMPLATE_FAILED, TITLE_FAILED); sendForAllAuhtors(variables, paper, TEMPLATE_FAILED, TITLE_FAILED);
} }

View File

@ -5,24 +5,15 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import ru.ulstu.deadline.model.Deadline; import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.deadline.service.DeadlineService; import ru.ulstu.deadline.service.DeadlineService;
import ru.ulstu.file.model.FileDataDto;
import ru.ulstu.file.service.FileService; import ru.ulstu.file.service.FileService;
import ru.ulstu.paper.model.AutoCompleteData;
import ru.ulstu.paper.model.Paper; import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.model.PaperDto; import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.paper.model.PaperListDto; import ru.ulstu.paper.model.PaperFilterDto;
import ru.ulstu.paper.model.Reference;
import ru.ulstu.paper.model.ReferenceDto;
import ru.ulstu.paper.repository.PaperRepository; import ru.ulstu.paper.repository.PaperRepository;
import ru.ulstu.paper.repository.ReferenceRepository;
import ru.ulstu.ping.service.PingService;
import ru.ulstu.timeline.service.EventService;
import ru.ulstu.user.model.User; import ru.ulstu.user.model.User;
import ru.ulstu.user.service.UserService; import ru.ulstu.user.service.UserService;
import java.io.IOException; import java.io.IOException;
import java.text.MessageFormat;
import java.time.temporal.ChronoUnit;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
@ -30,50 +21,32 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
import static org.springframework.util.ObjectUtils.isEmpty; import static org.springframework.util.ObjectUtils.isEmpty;
import static ru.ulstu.core.util.StreamApiUtils.convert; import static ru.ulstu.core.util.StreamApiUtils.convert;
import static ru.ulstu.paper.model.Paper.PaperStatus.ATTENTION; import static ru.ulstu.paper.model.Paper.PaperStatus.ATTENTION;
import static ru.ulstu.paper.model.Paper.PaperStatus.COMPLETED;
import static ru.ulstu.paper.model.Paper.PaperStatus.DRAFT; import static ru.ulstu.paper.model.Paper.PaperStatus.DRAFT;
import static ru.ulstu.paper.model.Paper.PaperStatus.FAILED;
import static ru.ulstu.paper.model.Paper.PaperStatus.ON_PREPARATION; import static ru.ulstu.paper.model.Paper.PaperStatus.ON_PREPARATION;
import static ru.ulstu.paper.model.Paper.PaperType.OTHER;
import static ru.ulstu.paper.model.ReferenceDto.FormatStandard.GOST;
import static ru.ulstu.paper.model.ReferenceDto.ReferenceType.ARTICLE;
import static ru.ulstu.paper.model.ReferenceDto.ReferenceType.BOOK;
@Service @Service
@Transactional
public class PaperService { public class PaperService {
private final static int MAX_DISPLAY_SIZE = 40; private final static int MAX_DISPLAY_SIZE = 40;
private final static String PAPER_FORMATTED_TEMPLATE = "%s %s";
private final PaperNotificationService paperNotificationService; private final PaperNotificationService paperNotificationService;
private final PaperRepository paperRepository; private final PaperRepository paperRepository;
private final UserService userService; private final UserService userService;
private final DeadlineService deadlineService; private final DeadlineService deadlineService;
private final FileService fileService; private final FileService fileService;
private final EventService eventService;
private final ReferenceRepository referenceRepository;
private final PingService pingService;
public PaperService(PaperRepository paperRepository, public PaperService(PaperRepository paperRepository,
ReferenceRepository referenceRepository,
FileService fileService, FileService fileService,
PaperNotificationService paperNotificationService, PaperNotificationService paperNotificationService,
UserService userService, UserService userService,
DeadlineService deadlineService, DeadlineService deadlineService) {
EventService eventService,
PingService pingService) {
this.paperRepository = paperRepository; this.paperRepository = paperRepository;
this.referenceRepository = referenceRepository;
this.fileService = fileService; this.fileService = fileService;
this.paperNotificationService = paperNotificationService; this.paperNotificationService = paperNotificationService;
this.userService = userService; this.userService = userService;
this.deadlineService = deadlineService; this.deadlineService = deadlineService;
this.eventService = eventService;
this.pingService = pingService;
} }
public List<Paper> findAll() { public List<Paper> findAll() {
@ -81,59 +54,34 @@ public class PaperService {
} }
public List<PaperDto> findAllDto() { public List<PaperDto> findAllDto() {
return convert(findAll(), PaperDto::new); List<PaperDto> papers = convert(findAll(), PaperDto::new);
} papers.forEach(paperDto -> paperDto.setTitle(StringUtils.abbreviate(paperDto.getTitle(), MAX_DISPLAY_SIZE)));
return papers;
public List<Paper> findAllActive() {
return findAll()
.stream()
.filter(paper -> paper.getStatus() != COMPLETED && paper.getStatus() != FAILED)
.collect(toList());
}
public List<Paper> findAllActiveByCurrentUser() {
return findAllActive()
.stream()
.filter(paper -> paper.getAuthors().contains(userService.getCurrentUser()))
.collect(toList());
}
public List<PaperDto> findAllActiveDto() {
return convert(findAllActive(), PaperDto::new);
} }
public PaperDto findOneDto(Integer id) { public PaperDto findOneDto(Integer id) {
return new PaperDto(paperRepository.findById(id).orElseThrow()); return new PaperDto(paperRepository.findOne(id));
} }
@Transactional @Transactional
public Integer create(PaperDto paperDto) throws IOException { public Integer create(PaperDto paperDto) throws IOException {
Paper newPaper = copyFromDto(new Paper(), paperDto); Paper newPaper = copyFromDto(new Paper(), paperDto);
return create(newPaper).getId(); newPaper = paperRepository.save(newPaper);
}
@Transactional
public Paper create(Paper paper) {
Paper newPaper = paperRepository.save(paper);
newPaper.setCreateDate(new Date());
paperNotificationService.sendCreateNotification(newPaper); paperNotificationService.sendCreateNotification(newPaper);
return newPaper; return newPaper.getId();
} }
private Paper copyFromDto(Paper paper, PaperDto paperDto) throws IOException { private Paper copyFromDto(Paper paper, PaperDto paperDto) throws IOException {
paper.setComment(paperDto.getComment()); paper.setComment(paperDto.getComment());
paper.setUrl(paperDto.getUrl());
paper.setCreateDate(paper.getCreateDate() == null ? new Date() : paper.getCreateDate()); paper.setCreateDate(paper.getCreateDate() == null ? new Date() : paper.getCreateDate());
paper.setLocked(paperDto.getLocked()); paper.setLocked(paperDto.getLocked());
paper.setStatus(paperDto.getStatus() == null ? DRAFT : paperDto.getStatus()); paper.setStatus(paperDto.getStatus() == null ? DRAFT : paperDto.getStatus());
paper.setType(paperDto.getType() == null ? OTHER : paperDto.getType());
paper.setTitle(paperDto.getTitle()); paper.setTitle(paperDto.getTitle());
paper.setUpdateDate(new Date()); paper.setUpdateDate(new Date());
paper.setDeadlines(deadlineService.saveOrCreate(paperDto.getDeadlines())); paper.setDeadlines(deadlineService.saveOrCreate(paperDto.getDeadlines()));
paper.setReferences(saveOrCreateReferences(paperDto.getReferences())); if (paperDto.getTmpFileName() != null) {
paper.setFiles(fileService.saveOrCreate(paperDto.getFiles().stream() paper.setFileData(fileService.createFileFromTmp(paperDto.getTmpFileName()));
.filter(f -> !f.isDeleted()) }
.collect(toList())));
paper.getAuthors().clear(); paper.getAuthors().clear();
if (paperDto.getAuthorIds() != null && !paperDto.getAuthorIds().isEmpty()) { if (paperDto.getAuthorIds() != null && !paperDto.getAuthorIds().isEmpty()) {
paperDto.getAuthorIds().forEach(authorIds -> paper.getAuthors().add(userService.findById(authorIds))); paperDto.getAuthorIds().forEach(authorIds -> paper.getAuthors().add(userService.findById(authorIds)));
@ -141,59 +89,15 @@ public class PaperService {
return paper; return paper;
} }
private List<Reference> saveOrCreateReferences(List<ReferenceDto> references) {
return references
.stream()
.filter(reference -> !reference.getDeleted())
.map(reference -> reference.getId() != null ? updateReference(reference) : createReference(reference))
.collect(Collectors.toList());
}
@Transactional
private Reference updateReference(ReferenceDto referenceDto) {
Reference updateReference = referenceRepository.getOne(referenceDto.getId());
copyFromDto(updateReference, referenceDto);
referenceRepository.save(updateReference);
return updateReference;
}
@Transactional
private Reference createReference(ReferenceDto referenceDto) {
Reference newReference = new Reference();
copyFromDto(newReference, referenceDto);
newReference = referenceRepository.save(newReference);
return newReference;
}
private Reference copyFromDto(Reference reference, ReferenceDto referenceDto) {
reference.setAuthors(referenceDto.getAuthors());
reference.setJournalOrCollectionTitle(referenceDto.getJournalOrCollectionTitle());
reference.setPages(referenceDto.getPages());
reference.setPublicationTitle(referenceDto.getPublicationTitle());
reference.setPublicationYear(referenceDto.getPublicationYear());
reference.setPublisher(referenceDto.getPublisher());
reference.setReferenceType(referenceDto.getReferenceType());
return reference;
}
@Transactional @Transactional
public Integer update(PaperDto paperDto) throws IOException { public Integer update(PaperDto paperDto) throws IOException {
Paper paper = paperRepository.getOne(paperDto.getId()); Paper paper = paperRepository.findOne(paperDto.getId());
Paper.PaperStatus oldStatus = paper.getStatus(); Paper.PaperStatus oldStatus = paper.getStatus();
Set<User> oldAuthors = new HashSet<>(paper.getAuthors()); Set<User> oldAuthors = new HashSet<>(paper.getAuthors());
if (paperDto.getTmpFileName() != null && paper.getFileData() != null) {
for (FileDataDto file : paperDto.getFiles().stream() fileService.deleteFile(paper.getFileData());
.filter(f -> f.isDeleted() && f.getId() != null)
.collect(toList())) {
fileService.delete(file.getId());
} }
paperRepository.save(copyFromDto(paper, paperDto)); paperRepository.save(copyFromDto(paper, paperDto));
for (ReferenceDto referenceDto : paperDto.getReferences().stream()
.filter(f -> f.getDeleted() && f.getId() != null)
.collect(toList())) {
referenceRepository.deleteById(referenceDto.getId());
}
eventService.updatePaperDeadlines(paper);
paper.getAuthors().forEach(author -> { paper.getAuthors().forEach(author -> {
if (!oldAuthors.contains(author)) { if (!oldAuthors.contains(author)) {
@ -209,46 +113,18 @@ public class PaperService {
} }
@Transactional @Transactional
public Integer update(Paper newPaper) { public void delete(Integer paperId) throws IOException {
Paper oldPaper = paperRepository.getOne(newPaper.getId()); Paper paper = paperRepository.findOne(paperId);
Paper.PaperStatus oldStatus = oldPaper.getStatus(); if (paper.getFileData() != null) {
Set<User> oldAuthors = new HashSet<>(oldPaper.getAuthors()); fileService.deleteFile(paper.getFileData());
newPaper.setUpdateDate(new Date());
newPaper = paperRepository.save(newPaper);
for (User author : newPaper.getAuthors()) {
if (!oldAuthors.contains(author)) {
paperNotificationService.sendCreateNotification(newPaper);
} }
} paperRepository.delete(paper);
if (newPaper.getStatus() != oldStatus) {
paperNotificationService.statusChangeNotification(newPaper, oldStatus);
}
return newPaper.getId();
}
@Transactional
public void delete(Integer paperId) {
delete(paperRepository.getOne(paperId));
} }
public List<Paper.PaperStatus> getPaperStatuses() { public List<Paper.PaperStatus> getPaperStatuses() {
return Arrays.asList(Paper.PaperStatus.values()); return Arrays.asList(Paper.PaperStatus.values());
} }
public List<Paper.PaperType> getPaperTypes() {
return Arrays.asList(Paper.PaperType.values());
}
public List<ReferenceDto.FormatStandard> getFormatStandards() {
return Arrays.asList(ReferenceDto.FormatStandard.values());
}
public List<ReferenceDto.ReferenceType> getReferenceTypes() {
return Arrays.asList(ReferenceDto.ReferenceType.values());
}
@Transactional @Transactional
public Paper create(String title, User user, Date deadlineDate) { public Paper create(String title, User user, Date deadlineDate) {
Paper paper = new Paper(); Paper paper = new Paper();
@ -258,16 +134,14 @@ public class PaperService {
paper.setCreateDate(new Date()); paper.setCreateDate(new Date());
paper.setUpdateDate(new Date()); paper.setUpdateDate(new Date());
paper.setStatus(DRAFT); paper.setStatus(DRAFT);
paper.setType(OTHER);
paper = paperRepository.save(paper); paper = paperRepository.save(paper);
paperNotificationService.sendCreateNotification(paper); paperNotificationService.sendCreateNotification(paper);
eventService.createFromPaper(paper);
return paper; return paper;
} }
public List<PaperDto> filter(PaperListDto filterDto) { public List<PaperDto> filter(PaperFilterDto filterDto) {
return convert(sortPapers(paperRepository.filter( return convert(sortPapers(paperRepository.filter(
filterDto.getFilterAuthorId() == null ? null : userService.findById(filterDto.getFilterAuthorId()), filterDto.getFilterAuthorId() == null ? null : userService.findById(filterDto.getFilterAuthorId()),
filterDto.getYear())), PaperDto::new); filterDto.getYear())), PaperDto::new);
@ -282,7 +156,7 @@ public class PaperService {
return statusCompareResult; return statusCompareResult;
} }
return paper1.getTitle().compareTo(paper2.getTitle()); return paper1.getTitle().compareTo(paper2.getTitle());
}).collect(toList()); }).collect(Collectors.toList());
} }
public PaperDto findPaper(int id) { public PaperDto findPaper(int id) {
@ -292,11 +166,12 @@ public class PaperService {
public void closeFailedPapers() { public void closeFailedPapers() {
List<Paper> papers = paperRepository.findAll() List<Paper> papers = paperRepository.findAll()
.stream() .stream()
.filter(paper -> paper.lastDeadlineFailed() .filter(paper -> paper.getNextDeadline().isPresent()
&& (paper.getStatus() == ON_PREPARATION && (paper.getStatus() == ON_PREPARATION
|| paper.getStatus() == DRAFT || paper.getStatus() == DRAFT
|| paper.getStatus() == ATTENTION)) || paper.getStatus() == ATTENTION)
.collect(toList()); && paper.getNextDeadline().get().getDate().before(new Date()))
.collect(Collectors.toList());
papers.forEach(paper -> { papers.forEach(paper -> {
Paper.PaperStatus oldStatus = paper.getStatus(); Paper.PaperStatus oldStatus = paper.getStatus();
paper.setStatus(Paper.PaperStatus.FAILED); paper.setStatus(Paper.PaperStatus.FAILED);
@ -313,133 +188,11 @@ public class PaperService {
} }
} }
public void save(Paper paper) {
if (isEmpty(paper.getId())) {
create(paper);
} else {
update(paper);
}
}
public PaperDto findById(Integer paperId) { public PaperDto findById(Integer paperId) {
return new PaperDto(paperRepository.getOne(paperId)); return new PaperDto(paperRepository.findOne(paperId));
}
public Paper findPaperById(Integer paperId) {
return paperRepository.getOne(paperId);
}
public List<Paper> findAllNotSelect(List<Integer> paperIds) {
if (!paperIds.isEmpty()) {
return sortPapers(paperRepository.findByIdNotInAndConferenceIsNullAndStatusNot(paperIds, COMPLETED));
} else {
return sortPapers(paperRepository.findByConferenceIsNullAndStatusNot(COMPLETED));
}
}
public List<PaperDto> findAllNotCompleted() {
return convert(paperRepository.findByStatusNot(COMPLETED), PaperDto::new);
}
public List<PaperDto> findAllSelect(List<Integer> paperIds) {
return convert(paperRepository.findAllByIdIn(paperIds), PaperDto::new);
} }
public List<User> getPaperAuthors() { public List<User> getPaperAuthors() {
return userService.findAll(); return userService.findAll();
} }
public List<String> getFormattedPaperList() {
return findAllCompleted()
.stream()
.map(paper -> String.format(PAPER_FORMATTED_TEMPLATE, paper.getTitle(), getAuthors(paper)))
.collect(toList());
}
private List<Paper> findAllCompleted() {
return findAll()
.stream()
.filter(paper -> paper.getStatus() == COMPLETED)
.collect(toList());
}
private String getAuthors(Paper paper) {
return paper.getAuthors()
.stream()
.map(User::getUserAbbreviate)
.collect(Collectors.joining(", "));
}
public String getFormattedReference(ReferenceDto referenceDto) {
return referenceDto.getFormatStandard() == GOST
? getGostReference(referenceDto)
: getSpringerReference(referenceDto);
}
public String getFormattedReferences(PaperDto paperDto) {
return String.join("\r\n", paperDto.getReferences()
.stream()
.filter(r -> !r.getDeleted())
.map(r -> {
r.setFormatStandard(paperDto.getFormatStandard());
return getFormattedReference(r);
})
.collect(Collectors.toList()));
}
private String getGostReference(ReferenceDto referenceDto) {
return MessageFormat.format(referenceDto.getReferenceType() == BOOK ? "{0} {1} - {2}{3}. - {4}с." : "{0} {1}{5} {2}{3}. С. {4}.",
referenceDto.getAuthors(),
referenceDto.getPublicationTitle(),
StringUtils.isEmpty(referenceDto.getPublisher()) ? "" : referenceDto.getPublisher() + ", ",
referenceDto.getPublicationYear() != null ? referenceDto.getPublicationYear().toString() : "",
referenceDto.getPages(),
StringUtils.isEmpty(referenceDto.getJournalOrCollectionTitle()) ? "." : " // " + referenceDto.getJournalOrCollectionTitle() + ".");
}
private String getSpringerReference(ReferenceDto referenceDto) {
return MessageFormat.format("{0} ({1}) {2}.{3} {4}pp {5}",
referenceDto.getAuthors(),
referenceDto.getPublicationYear() != null ? referenceDto.getPublicationYear().toString() : "",
referenceDto.getPublicationTitle(),
referenceDto.getReferenceType() == ARTICLE ? " " + referenceDto.getJournalOrCollectionTitle() + "," : "",
StringUtils.isEmpty(referenceDto.getPublisher()) ? "" : referenceDto.getPublisher() + ", ",
referenceDto.getPages());
}
public List<Paper> findAllCompletedByType(Paper.PaperType type) {
return paperRepository.findByTypeAndStatus(type, Paper.PaperStatus.COMPLETED);
}
public AutoCompleteData getAutoCompleteData() {
AutoCompleteData autoCompleteData = new AutoCompleteData();
autoCompleteData.setAuthors(referenceRepository.findDistinctAuthors());
autoCompleteData.setJournalOrCollectionTitles(referenceRepository.findDistinctJournalOrCollectionTitles());
autoCompleteData.setPublicationTitles(referenceRepository.findDistinctPublicationTitles());
autoCompleteData.setPublishers(referenceRepository.findDistinctPublishers());
return autoCompleteData;
}
@Transactional
public void ping(int paperId) throws IOException {
pingService.addPing(findPaperById(paperId));
}
public void createByTitle(String newPaperTitle) {
Paper paper = new Paper();
paper.setTitle(newPaperTitle);
paper.setStatus(DRAFT);
paper.getAuthors().add(userService.getCurrentUser());
paper.getDeadlines().add(deadlineService.createWithOffset(new Date(), 1, ChronoUnit.WEEKS));
create(paper);
}
public void delete(List<Paper> papers) {
papers.forEach(paper -> delete(paper));
}
public void delete(Paper paper) {
deadlineService.delete(paper.getDeadlines());
paperRepository.delete(paper);
}
} }

View File

@ -1,82 +0,0 @@
package ru.ulstu.ping.model;
import jakarta.persistence.Column;
import jakarta.persistence.DiscriminatorType;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import org.hibernate.annotations.Any;
import org.hibernate.annotations.AnyDiscriminator;
import org.hibernate.annotations.AnyDiscriminatorValue;
import org.hibernate.annotations.AnyKeyJavaClass;
import org.springframework.format.annotation.DateTimeFormat;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.core.model.UserActivity;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.project.model.Project;
import ru.ulstu.user.model.User;
import java.util.Date;
@Entity
@Table(name = "ping")
public class Ping extends BaseEntity {
@Temporal(value = TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date date;
@ManyToOne(optional = false)
@JoinColumn(name = "users_id")
private User user;
@Column(name = "activity_type", insertable = false, updatable = false)
private String activityType;
@Any
@AnyDiscriminator(DiscriminatorType.STRING)
@AnyKeyJavaClass(Integer.class)
@JoinColumn(name = "activity_id")
@Column(name = "activity_type")
@AnyDiscriminatorValue(entity = Conference.class, discriminator = "CONFERENCE")
@AnyDiscriminatorValue(entity = Paper.class, discriminator = "PAPER")
@AnyDiscriminatorValue(entity = Project.class, discriminator = "PROJECT")
@AnyDiscriminatorValue(entity = Grant.class, discriminator = "GRANT")
private UserActivity activity;
public Ping() {
}
public Ping(Date date, User user) {
this.date = date;
this.user = user;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public UserActivity getActivity() {
return this.activity;
}
public void setActivity(UserActivity activity) {
this.activity = activity;
}
}

View File

@ -1,35 +0,0 @@
package ru.ulstu.ping.model;
import ru.ulstu.user.model.User;
import java.util.ArrayList;
import java.util.List;
public class PingInfo {
private User user;
private List<Ping> pings = new ArrayList<>();
public PingInfo(User user) {
this.user = user;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<Ping> getPings() {
return pings;
}
public void setPings(List<Ping> pings) {
this.pings = pings;
}
public void addPing(Ping ping) {
this.pings.add(ping);
}
}

Some files were not shown because too many files have changed in this diff Show More