package ru.ulstu.paper.service; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.ulstu.deadline.model.Deadline; import ru.ulstu.deadline.service.DeadlineService; import ru.ulstu.file.model.FileDataDto; import ru.ulstu.file.service.FileService; import ru.ulstu.paper.model.Paper; import ru.ulstu.paper.model.PaperDto; import ru.ulstu.paper.model.PaperListDto; import ru.ulstu.paper.model.ReferenceDto; import ru.ulstu.paper.repository.PaperRepository; import ru.ulstu.timeline.service.EventService; import ru.ulstu.user.model.User; import ru.ulstu.user.service.UserService; import java.io.IOException; import java.text.MessageFormat; import java.util.Arrays; import java.util.Date; import java.util.HashSet; 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 ru.ulstu.core.util.StreamApiUtils.convert; 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.FAILED; 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 public class PaperService { private final static int MAX_DISPLAY_SIZE = 40; private final static String PAPER_FORMATTED_TEMPLATE = "%s %s"; private final PaperNotificationService paperNotificationService; private final PaperRepository paperRepository; private final UserService userService; private final DeadlineService deadlineService; private final FileService fileService; private final EventService eventService; public PaperService(PaperRepository paperRepository, FileService fileService, PaperNotificationService paperNotificationService, UserService userService, DeadlineService deadlineService, EventService eventService) { this.paperRepository = paperRepository; this.fileService = fileService; this.paperNotificationService = paperNotificationService; this.userService = userService; this.deadlineService = deadlineService; this.eventService = eventService; } public List findAll() { return sortPapers(paperRepository.findAll()); } public List findAllDto() { List papers = convert(findAll(), PaperDto::new); papers.forEach(paperDto -> paperDto.setTitle(StringUtils.abbreviate(paperDto.getTitle(), MAX_DISPLAY_SIZE))); return papers; } public List findAllActive() { return findAll() .stream() .filter(paper -> paper.getStatus() != COMPLETED && paper.getStatus() != FAILED) .collect(toList()); } public List findAllActiveDto() { return convert(findAllActive(), PaperDto::new); } public PaperDto findOneDto(Integer id) { return new PaperDto(paperRepository.findOne(id)); } @Transactional public Integer create(PaperDto paperDto) throws IOException { Paper newPaper = copyFromDto(new Paper(), paperDto); newPaper = paperRepository.save(newPaper); paperNotificationService.sendCreateNotification(newPaper); eventService.createFromPaper(newPaper); return newPaper.getId(); } @Transactional public Paper create(Paper paper) { Paper newPaper = paperRepository.save(paper); paperNotificationService.sendCreateNotification(newPaper); eventService.createFromPaper(newPaper); return newPaper; } private Paper copyFromDto(Paper paper, PaperDto paperDto) throws IOException { paper.setComment(paperDto.getComment()); paper.setUrl(paperDto.getUrl()); paper.setLatexText(paperDto.getLatexText()); paper.setCreateDate(paper.getCreateDate() == null ? new Date() : paper.getCreateDate()); paper.setLocked(paperDto.getLocked()); paper.setStatus(paperDto.getStatus() == null ? DRAFT : paperDto.getStatus()); paper.setType(paperDto.getType() == null ? OTHER : paperDto.getType()); paper.setTitle(paperDto.getTitle()); paper.setUpdateDate(new Date()); paper.setDeadlines(deadlineService.saveOrCreate(paperDto.getDeadlines())); paper.setFiles(fileService.saveOrCreate(paperDto.getFiles().stream() .filter(f -> !f.isDeleted()) .collect(toList()))); paper.getAuthors().clear(); if (paperDto.getAuthorIds() != null && !paperDto.getAuthorIds().isEmpty()) { paperDto.getAuthorIds().forEach(authorIds -> paper.getAuthors().add(userService.findById(authorIds))); } return paper; } @Transactional public Integer update(PaperDto paperDto) throws IOException { Paper paper = paperRepository.findOne(paperDto.getId()); Paper.PaperStatus oldStatus = paper.getStatus(); Set oldAuthors = new HashSet<>(paper.getAuthors()); for (FileDataDto file : paperDto.getFiles().stream() .filter(f -> f.isDeleted() && f.getId() != null) .collect(toList())) { fileService.delete(file.getId()); } paperRepository.save(copyFromDto(paper, paperDto)); eventService.updatePaperDeadlines(paper); paper.getAuthors().forEach(author -> { if (!oldAuthors.contains(author)) { paperNotificationService.sendCreateNotification(paper); } }); if (paper.getStatus() != oldStatus) { paperNotificationService.statusChangeNotification(paper, oldStatus); } return paper.getId(); } @Transactional public void delete(Integer paperId) { Paper paper = paperRepository.findOne(paperId); paperRepository.delete(paper); } public List getPaperStatuses() { return Arrays.asList(Paper.PaperStatus.values()); } public List getPaperTypes() { return Arrays.asList(Paper.PaperType.values()); } @Transactional public Paper create(String title, User user, Date deadlineDate) { Paper paper = new Paper(); paper.setTitle(title); paper.getAuthors().add(user); paper.getDeadlines().add(new Deadline(deadlineDate, "первый дедлайн")); paper.setCreateDate(new Date()); paper.setUpdateDate(new Date()); paper.setStatus(DRAFT); paper.setType(OTHER); paper = paperRepository.save(paper); paperNotificationService.sendCreateNotification(paper); eventService.createFromPaper(paper); return paper; } public List filter(PaperListDto filterDto) { return convert(sortPapers(paperRepository.filter( filterDto.getFilterAuthorId() == null ? null : userService.findById(filterDto.getFilterAuthorId()), filterDto.getYear())), PaperDto::new); } private List sortPapers(List papers) { return papers.stream().sorted((paper1, paper2) -> { int statusCompareResult = Integer.valueOf(Arrays.asList(Paper.PaperStatus.values()).indexOf(paper1.getStatus())) .compareTo(Arrays.asList(Paper.PaperStatus.values()).indexOf(paper2.getStatus())); if (statusCompareResult != 0) { return statusCompareResult; } return paper1.getTitle().compareTo(paper2.getTitle()); }).collect(toList()); } public PaperDto findPaper(int id) { return new PaperDto(paperRepository.getOne(id)); } public void closeFailedPapers() { List papers = paperRepository.findAll() .stream() .filter(paper -> paper.lastDeadlineFailed() && (paper.getStatus() == ON_PREPARATION || paper.getStatus() == DRAFT || paper.getStatus() == ATTENTION)) .collect(toList()); papers.forEach(paper -> { Paper.PaperStatus oldStatus = paper.getStatus(); paper.setStatus(Paper.PaperStatus.FAILED); paperRepository.save(paper); paperNotificationService.sendFailedNotification(paper, oldStatus); }); } public void save(PaperDto paperDto) throws IOException { if (isEmpty(paperDto.getId())) { create(paperDto); } else { update(paperDto); } } public PaperDto findById(Integer paperId) { return new PaperDto(paperRepository.findOne(paperId)); } public Paper findPaperById(Integer paperId) { return paperRepository.findOne(paperId); } public List findAllNotSelect(List paperIds) { if (!paperIds.isEmpty()) { return sortPapers(paperRepository.findByIdNotIn(paperIds)); } else { return sortPapers(paperRepository.findAll()); } } public List findAllSelect(List paperIds) { return sortPapers(paperRepository.findAllByIdIn(paperIds)); } public List getPaperAuthors() { return userService.findAll(); } public List getFormattedPaperList() { return findAllCompleted() .stream() .map(paper -> String.format(PAPER_FORMATTED_TEMPLATE, paper.getTitle(), getAuthors(paper))) .collect(toList()); } private List 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 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().toString(), referenceDto.getPages(), StringUtils.isEmpty(referenceDto.getJournalOrCollectionTitle()) ? "." : " // " + referenceDto.getJournalOrCollectionTitle() + "."); } public String getSpringerReference(ReferenceDto referenceDto) { return MessageFormat.format("{0} ({1}) {2}.{3} {4}pp {5}", referenceDto.getAuthors(), referenceDto.getPublicationYear().toString(), referenceDto.getPublicationTitle(), referenceDto.getReferenceType() == ARTICLE ? " " + referenceDto.getJournalOrCollectionTitle() + "," : "", StringUtils.isEmpty(referenceDto.getPublisher()) ? "" : referenceDto.getPublisher() + ", ", referenceDto.getPages()); } public List findAllCompletedByType(Paper.PaperType type) { return paperRepository.findByTypeAndStatus(type, Paper.PaperStatus.COMPLETED); } }