Enforce code formatting via Prettier ()

Fixes  by introducing [Prettier](https://prettier.io/).

Prettier is an extremely opinionated formatter. It will reformat every single line according to its style. There are virtually no configuration options so there can be no discussion about formatting rules.

There are two parameters that are configurable; indent length and line length. Indent length has been set to 4 because that's the Java standard.

Line length defaults to 80 but has been increased to 100. The rational for this is that Prettier was created for JavaScript which is much less verbose than Java. Not only does every Java line start with 8 spaces of indentation vs. JavaScripts 0 or 2, it also has types wile JavaScript does not and uses `const` for variable declarations. Compare the two below examples as well as an actual example from the source code that is too long for the default 80 characters. I have no problem dropping down to the default 80 if that is preferred I just felt that with the average length of a line of Java code being pretty long, excessive wrapping would reduce readability.

```javascript
  const attributes = {
    ...
  };
```
```java
        Map<String, String> attributes = Map.of(
            ...
        );
```

Or the following real code which is 97 characters long.
```java
        Set<ProjectParticipant> contributors = daisyAPI.getContributors(project.getIdentifier());
```

Reviewed-on: 
Reviewed-by: Tom Zhao <tom.zhao@dsv.su.se>
Co-authored-by: Andreas Svanberg <andreass@dsv.su.se>
Co-committed-by: Andreas Svanberg <andreass@dsv.su.se>
This commit is contained in:
Andreas Svanberg 2024-12-02 14:17:59 +01:00 committed by Tom Zhao
parent 03ad12f435
commit 1554d4bc27
1682 changed files with 41209 additions and 27692 deletions
.gitattributes.gitignore.prettierrc.yamlREADME.md
api/src/main/java/se/su/dsv/scipro/api
core/src/main/java/se/su/dsv/scipro
CoreConfig.javaDataInitializer.javaRepositoryConfiguration.java
activityplan
checklist
daisyExternal
data
date
file
finalseminar

5
.gitattributes vendored Normal file

@ -0,0 +1,5 @@
# Prettier enforces LF line endings in all files
# If git is configured with core.autocrlf=true, it may convert LF to CRLF when
# checking out files depending on your OS. This will cause Prettier to change it
# causing Git to show every file as modified.
*.java text eol=lf

1
.gitignore vendored

@ -25,3 +25,4 @@ fitnesse/target/
daisy-integration/target/
war/target/
api/target/
node_modules/

4
.prettierrc.yaml Normal file

@ -0,0 +1,4 @@
tabWidth: 4
printWidth: 120
plugins:
- prettier-plugin-java

@ -11,3 +11,17 @@ and get an access token.
Once the token has been obtained go to the [Swagger UI](http://localhost:8080/api/swagger) to interact with the API.
Click the "Authorize" button in the top right and paste the access token to log in.
## Code formatting
This project uses [prettier-java](https://github.com/jhipster/prettier-java)
to format all Java code. To reformat the code run
`./mvnw validate frontend:npm@reformat -pl .`.
Yes it's a mouthful but unfortunately the [prettier-maven-plugin](https://github.com/HubSpot/prettier-maven-plugin)
does not work due to an [outstanding issue](https://github.com/HubSpot/prettier-maven-plugin/issues/79).
An easier way to reformat code is to set IntelliJ to do it on save. Go to
`Settings -> Language & Frameworks -> JavaScript -> Prettier` and then check
`Automatic Prettier Configuration`, set `Run for files` to `**/*.{java}`,
and finally check `Run on save`.
The formatting is validated by CI, but you should do it beforehand with a simple `./mvnw verify -pl .`.

@ -1,16 +1,16 @@
package se.su.dsv.scipro.api;
import jakarta.inject.Inject;
import java.util.Optional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import se.su.dsv.scipro.system.User;
import se.su.dsv.scipro.system.UserService;
import java.util.Optional;
@RestController
public class ApiController {
private final UserService userService;
@Inject

@ -3,6 +3,8 @@ package se.su.dsv.scipro;
import com.google.common.eventbus.EventBus;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import java.time.Clock;
import java.util.Set;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -201,11 +203,9 @@ import se.su.dsv.scipro.system.UserServiceImpl;
import se.su.dsv.scipro.thesislink.ExternalLinkServiceImpl;
import se.su.dsv.scipro.workerthreads.WorkerDataServiceImpl;
import java.time.Clock;
import java.util.Set;
@Configuration(proxyBeanMethods = false)
public class CoreConfig {
@Bean
public EventBus eventBus() {
return new EventBus();
@ -221,8 +221,8 @@ public class CoreConfig {
@Value("${oauth.uri}") String uri,
@Value("${oauth.redirectUri}") String redirectUri,
@Value("${oauth.clientId}") String clientId,
@Value("${oauth.clientSecret}") String clientSecret)
{
@Value("${oauth.clientSecret}") String clientSecret
) {
return new OAuthSettings(uri, redirectUri, clientId, clientSecret);
}
@ -235,8 +235,8 @@ public class CoreConfig {
public DaisyAPIImpl daisyAPI(
@Value("${daisy.api.url}") final String baseUrl,
@Value("${daisy.api.username}") final String user,
@Value("${daisy.api.password}") final String password)
{
@Value("${daisy.api.password}") final String password
) {
return new DaisyAPIImpl(baseUrl, user, password);
}
@ -256,9 +256,15 @@ public class CoreConfig {
FileService fileDescriptionService,
EventBus eventBus,
DaysService daysService,
ReviewerDeadlineSettingsService reviewerDeadlineSettingsService)
{
return new FinalSeminarApprovalServiceImpl(em, fileDescriptionService, eventBus, daysService, reviewerDeadlineSettingsService);
ReviewerDeadlineSettingsService reviewerDeadlineSettingsService
) {
return new FinalSeminarApprovalServiceImpl(
em,
fileDescriptionService,
eventBus,
daysService,
reviewerDeadlineSettingsService
);
}
@Bean
@ -267,9 +273,15 @@ public class CoreConfig {
FileService fileDescriptionService,
EventBus eventBus,
DaysService daysService,
ReviewerDeadlineSettingsService reviewerDeadlineSettingsService)
{
return new RoughDraftApprovalServiceImpl(em, eventBus, fileDescriptionService, daysService, reviewerDeadlineSettingsService);
ReviewerDeadlineSettingsService reviewerDeadlineSettingsService
) {
return new RoughDraftApprovalServiceImpl(
em,
eventBus,
fileDescriptionService,
daysService,
reviewerDeadlineSettingsService
);
}
@Bean
@ -294,10 +306,14 @@ public class CoreConfig {
ChecklistTemplateService checklistTemplateService,
DaysService daysService,
FileService fileService
)
{
return new ActivityPlanFacadeImpl(eventBus, projectFileService, checklistTemplateService, daysService,
fileService);
) {
return new ActivityPlanFacadeImpl(
eventBus,
projectFileService,
checklistTemplateService,
daysService,
fileService
);
}
@Bean
@ -321,10 +337,7 @@ public class CoreConfig {
}
@Bean
public LocalAuthentication localAuthentication(
UserService userService,
PasswordService passwordService)
{
public LocalAuthentication localAuthentication(UserService userService, PasswordService passwordService) {
return new LocalAuthentication(userService, passwordService);
}
@ -334,10 +347,15 @@ public class CoreConfig {
ForumPostReadStateRepository readStateRepository,
AbstractThreadRepository threadRepository,
FileService fileService,
EventBus eventBus)
{
return new BasicForumServiceImpl(forumPostRepository, readStateRepository, threadRepository, fileService,
eventBus);
EventBus eventBus
) {
return new BasicForumServiceImpl(
forumPostRepository,
readStateRepository,
threadRepository,
fileService,
eventBus
);
}
@Bean
@ -373,8 +391,8 @@ public class CoreConfig {
@Bean
public DeliveryConfigurationServiceImpl deliveryConfigurationService(
Provider<EntityManager> em,
UserProfileService userProfileService)
{
UserProfileService userProfileService
) {
return new DeliveryConfigurationServiceImpl(em, userProfileService);
}
@ -398,13 +416,15 @@ public class CoreConfig {
Provider<EntityManager> em,
FileStore fileStore,
FileReferenceRepository fileReferenceRepository,
FileDescriptionRepo fileDescriptionRepository)
{
FileDescriptionRepo fileDescriptionRepository
) {
return new FileServiceImpl(em, fileReferenceRepository, fileDescriptionRepository, fileStore);
}
@Bean
public FinalSeminarActiveParticipationServiceImpl finalSeminarActiveParticipationService(Provider<EntityManager> em) {
public FinalSeminarActiveParticipationServiceImpl finalSeminarActiveParticipationService(
Provider<EntityManager> em
) {
return new FinalSeminarActiveParticipationServiceImpl(em);
}
@ -428,8 +448,8 @@ public class CoreConfig {
FinalSeminarActiveParticipationRepository finalSeminarActiveParticipationRepository,
FinalSeminarRepository finalSeminarRepository,
Clock clock,
RoughDraftApprovalService roughDraftApprovalService)
{
RoughDraftApprovalService roughDraftApprovalService
) {
return new FinalSeminarServiceImpl(
em,
eventBus,
@ -439,7 +459,8 @@ public class CoreConfig {
finalSeminarActiveParticipationRepository,
finalSeminarRepository,
clock,
roughDraftApprovalService);
roughDraftApprovalService
);
}
@Bean
@ -455,10 +476,17 @@ public class CoreConfig {
ProjectFileService projectFileService,
ProjectService projectService,
FinalSeminarSettingsService finalSeminarSettingsService,
PlagiarismControl plagiarismControl)
{
return new FinalSeminarUploadControllerImpl(projectService, fileService, finalSeminarSettingsService,
finalSeminarService, eventBus, projectFileService, plagiarismControl);
PlagiarismControl plagiarismControl
) {
return new FinalSeminarUploadControllerImpl(
projectService,
fileService,
finalSeminarSettingsService,
finalSeminarService,
eventBus,
projectFileService,
plagiarismControl
);
}
@Bean
@ -469,17 +497,24 @@ public class CoreConfig {
FileService fileService,
EventBus eventBus,
PlagiarismControl plagiarismControl,
GradingReportService gradingReportService)
{
return new FinalThesisServiceImpl(em, notification, projectFile,
fileService, eventBus, plagiarismControl, gradingReportService);
GradingReportService gradingReportService
) {
return new FinalThesisServiceImpl(
em,
notification,
projectFile,
fileService,
eventBus,
plagiarismControl,
gradingReportService
);
}
@Bean
public FirstMeetingServiceImpl firstMeetingService(
Provider<EntityManager> em,
ActivityPlanFacade activityPlanFacade)
{
ActivityPlanFacade activityPlanFacade
) {
return new FirstMeetingServiceImpl(em, activityPlanFacade);
}
@ -505,23 +540,24 @@ public class CoreConfig {
Clock clock,
SupervisorGradingReportRepository supervisorGradingReportRepository,
GradingReportTemplateRepoImpl gradingReportTemplateRepo,
ProjectTypeService projectTypeService)
{
ProjectTypeService projectTypeService
) {
return new GradingReportServiceImpl(
eventBus,
thesisSubmissionHistoryService,
clock,
supervisorGradingReportRepository,
gradingReportTemplateRepo,
projectTypeService);
projectTypeService
);
}
@Bean
public GroupForumServiceImpl groupForumService(
EventBus eventBus,
GroupThreadRepository groupThreadRepository,
BasicForumService basicForumService)
{
BasicForumService basicForumService
) {
return new GroupForumServiceImpl(groupThreadRepository, basicForumService, eventBus);
}
@ -540,10 +576,19 @@ public class CoreConfig {
GeneralSystemSettingsService generalSystemSettingsService,
TargetRepository targetRepository,
IdeaRepository ideaRepository,
Clock clock)
{
return new IdeaServiceImpl(em, applicationPeriodService, firstMeetingRepository, notificationController,
projectService, generalSystemSettingsService, targetRepository, ideaRepository, clock);
Clock clock
) {
return new IdeaServiceImpl(
em,
applicationPeriodService,
firstMeetingRepository,
notificationController,
projectService,
generalSystemSettingsService,
targetRepository,
ideaRepository,
clock
);
}
@Bean
@ -573,8 +618,8 @@ public class CoreConfig {
@Bean
public MilestoneActivityTemplateServiceImpl milestoneActivityTemplateService(
MilestoneActivityTemplateRepository milestoneActivityTemplateRepository)
{
MilestoneActivityTemplateRepository milestoneActivityTemplateRepository
) {
return new MilestoneActivityTemplateServiceImpl(milestoneActivityTemplateRepository);
}
@ -586,8 +631,8 @@ public class CoreConfig {
@Bean
public MilestoneServiceImpl milestoneService(
Provider<EntityManager> em,
NotificationController notificationController)
{
NotificationController notificationController
) {
return new MilestoneServiceImpl(notificationController, em);
}
@ -598,8 +643,8 @@ public class CoreConfig {
@Bean
public NationalSubjectCategoryServiceImpl nationalSubjectCategoryService(
NationalSubjectCategoryRepository nationalSubjectCategoryRepository)
{
NationalSubjectCategoryRepository nationalSubjectCategoryRepository
) {
return new NationalSubjectCategoryServiceImpl(nationalSubjectCategoryRepository);
}
@ -623,10 +668,14 @@ public class CoreConfig {
OppositionReportRepo oppositionReportRepository,
GradingReportTemplateRepo gradingReportTemplateRepository,
FileService fileService,
FinalSeminarOppositionRepo finalSeminarOppositionRepository)
{
return new OppositionReportServiceImpl(oppositionReportRepository, gradingReportTemplateRepository,
fileService, finalSeminarOppositionRepository);
FinalSeminarOppositionRepo finalSeminarOppositionRepository
) {
return new OppositionReportServiceImpl(
oppositionReportRepository,
gradingReportTemplateRepository,
fileService,
finalSeminarOppositionRepository
);
}
@Bean
@ -642,26 +691,33 @@ public class CoreConfig {
EventBus eventBus,
ProjectFileService projectFileService,
DaysService daisyService,
Clock clock)
{
return new PeerPortalImpl(fileService, peerReviewRepository, peerRequestRepository,
eventBus, projectFileService, daisyService, clock);
Clock clock
) {
return new PeerPortalImpl(
fileService,
peerReviewRepository,
peerRequestRepository,
eventBus,
projectFileService,
daisyService,
clock
);
}
@Bean
public PeerRequestServiceImpl peerRequestService(
Provider<EntityManager> em,
EventBus eventBus,
FileService fileService)
{
FileService fileService
) {
return new PeerRequestServiceImpl(em, eventBus, fileService);
}
@Bean
public PeerReviewServiceImpl peerReviewService(
Provider<EntityManager> em,
PeerReviewRepository peerReviewRepository)
{
PeerReviewRepository peerReviewRepository
) {
return new PeerReviewServiceImpl(em, peerReviewRepository);
}
@ -669,8 +725,8 @@ public class CoreConfig {
public PlagiarismControlImpl plagiarismControl(
FileService fileService,
PlagiarismRequestRepository plagiarismRequestRepository,
UrkundSubmissionRepository urkundSubmissionRepository)
{
UrkundSubmissionRepository urkundSubmissionRepository
) {
return new PlagiarismControlImpl(plagiarismRequestRepository, urkundSubmissionRepository, fileService);
}
@ -687,8 +743,8 @@ public class CoreConfig {
@Bean
public ProjectFileServiceImpl projectFileService(
FileService fileService,
ProjectFileRepository projectFileRepository)
{
ProjectFileRepository projectFileRepository
) {
return new ProjectFileServiceImpl(fileService, projectFileRepository);
}
@ -703,10 +759,15 @@ public class CoreConfig {
BasicForumService basicForumService,
ProjectThreadRepository projectThreadRepository,
ForumPostRepository postRepository,
ProjectFileService projectFileService)
{
return new ProjectForumServiceImpl(projectThreadRepository,
postRepository, projectFileService, basicForumService, eventBus);
ProjectFileService projectFileService
) {
return new ProjectForumServiceImpl(
projectThreadRepository,
postRepository,
projectFileService,
basicForumService,
eventBus
);
}
@Bean
@ -724,8 +785,8 @@ public class CoreConfig {
Provider<EntityManager> em,
EventBus eventBus,
ProjectRepo projectRepo,
Clock clock)
{
Clock clock
) {
return new ProjectServiceImpl(projectRepo, clock, eventBus, em);
}
@ -736,8 +797,8 @@ public class CoreConfig {
@Bean
public PublicationMetadataServiceImpl publicationMetadataService(
PublicationMetadataRepository publicationMetadataRepository)
{
PublicationMetadataRepository publicationMetadataRepository
) {
return new PublicationMetadataServiceImpl(publicationMetadataRepository);
}
@ -745,8 +806,8 @@ public class CoreConfig {
public ReflectionServiceImpl reflectionService(
AuthorRepository authorRepository,
FinalSeminarServiceImpl finalSeminarService,
EventBus eventBus)
{
EventBus eventBus
) {
return new ReflectionServiceImpl(authorRepository, finalSeminarService, eventBus);
}
@ -774,11 +835,23 @@ public class CoreConfig {
GradingReportService gradingReportService,
ReviewerInteractionService reviewerInteractionService,
RoughDraftApprovalService roughDraftApprovalService,
FinalSeminarApprovalService finalSeminarApprovalService)
{
return new ZipReporter(fileService, projectService, finalSeminarService, projectForumService, peerReviewService,
peerRequestService, groupService, groupForumService, ideaService, gradingReportService,
reviewerInteractionService, roughDraftApprovalService, finalSeminarApprovalService);
FinalSeminarApprovalService finalSeminarApprovalService
) {
return new ZipReporter(
fileService,
projectService,
finalSeminarService,
projectForumService,
peerReviewService,
peerRequestService,
groupService,
groupForumService,
ideaService,
gradingReportService,
reviewerInteractionService,
roughDraftApprovalService,
finalSeminarApprovalService
);
}
@Bean
@ -795,8 +868,8 @@ public class CoreConfig {
public ReviewerInteractionServiceImpl reviewerInteractionService(
ReviewerThreadRepository reviewerThreadRepository,
BasicForumService forumService,
EventBus eventBus)
{
EventBus eventBus
) {
return new ReviewerInteractionServiceImpl(reviewerThreadRepository, forumService, eventBus);
}
@ -804,8 +877,8 @@ public class CoreConfig {
public ReviewingServiceImpl reviewingService(
Provider<EntityManager> em,
EventBus eventBus,
FileService fileService)
{
FileService fileService
) {
return new ReviewingServiceImpl(em, fileService, eventBus);
}
@ -815,16 +888,21 @@ public class CoreConfig {
DecisionRepository decisionRepository,
UserService userService,
ProjectService projectService,
EventBus eventBus)
{
return new ReviewerCapacityServiceImpl(reviewerTargetRepository, decisionRepository, userService,
projectService, eventBus);
EventBus eventBus
) {
return new ReviewerCapacityServiceImpl(
reviewerTargetRepository,
decisionRepository,
userService,
projectService,
eventBus
);
}
@Bean
public ReviewerDeadlineSettingsServiceImpl reviewerDeadlineSettingsService(
ReviewerDeadlineSettingsRepository reviewerDeadlineSettingsRepository)
{
ReviewerDeadlineSettingsRepository reviewerDeadlineSettingsRepository
) {
return new ReviewerDeadlineSettingsServiceImpl(reviewerDeadlineSettingsRepository);
}
@ -839,10 +917,15 @@ public class CoreConfig {
QuestionRepository questionRepository,
FinalThesisService finalThesisService,
GeneralSystemSettingsService generalSystemSettingsService,
ReflectionService reflectionService)
{
return new SurveyServiceImpl(surveyRepository, questionRepository, finalThesisService,
generalSystemSettingsService, reflectionService);
ReflectionService reflectionService
) {
return new SurveyServiceImpl(
surveyRepository,
questionRepository,
finalThesisService,
generalSystemSettingsService,
reflectionService
);
}
@Bean
@ -856,10 +939,7 @@ public class CoreConfig {
}
@Bean
public UrkundApiImpl urkundApi(
UrkundSettingsRepository urkundSettingsRepository,
FileService fileService)
{
public UrkundApiImpl urkundApi(UrkundSettingsRepository urkundSettingsRepository, FileService fileService) {
return new UrkundApiImpl(urkundSettingsRepository, fileService);
}
@ -868,8 +948,8 @@ public class CoreConfig {
UrkundApi urkundApi,
UrkundSubmissionRepository urkundSubmissionRepository,
Sukat sukat,
FileService fileService)
{
FileService fileService
) {
return new UrkundServiceImpl(urkundApi, urkundSubmissionRepository, sukat, fileService);
}
@ -900,11 +980,16 @@ public class CoreConfig {
MailEventService mailEventService,
ReceiverConfigurationService receiverConfigurationService,
DeliveryConfigurationService deliveryConfigurationService,
Provider<CurrentUser> currentUserProvider)
{
return new NotificationControllerImpl(notificationService,
Provider<CurrentUser> currentUserProvider
) {
return new NotificationControllerImpl(
notificationService,
notificationMailFormatter,
mailEventService, receiverConfigurationService, deliveryConfigurationService, currentUserProvider);
mailEventService,
receiverConfigurationService,
deliveryConfigurationService,
currentUserProvider
);
}
@Bean
@ -919,10 +1004,16 @@ public class CoreConfig {
RoughDraftApprovalService roughDraftApprovalService,
FinalSeminarApprovalService finalSeminarApprovalService,
DaysService daysService,
Clock clock)
{
return new ReviewerAssignedDeadline(roughDraftApprovalService, finalSeminarApprovalService,
reviewerDeadlineSettingsService, daysService, eventBus, clock);
Clock clock
) {
return new ReviewerAssignedDeadline(
roughDraftApprovalService,
finalSeminarApprovalService,
reviewerDeadlineSettingsService,
daysService,
eventBus,
clock
);
}
@Bean
@ -934,8 +1025,8 @@ public class CoreConfig {
public FinalSeminarActivityHandler finalSeminarActivityHandler(
ActivityPlanFacade activityPlanFacade,
ActivityFinalSeminarRepository activityFinalSeminarRepository,
EventBus eventBus)
{
EventBus eventBus
) {
return new FinalSeminarActivityHandler(activityPlanFacade, activityFinalSeminarRepository, eventBus);
}
@ -943,8 +1034,8 @@ public class CoreConfig {
public PostActivityUploadToForum postActivityUploadToForum(
EventBus eventBus,
ProjectForumService projectForumService,
ActivityThreadRepository activityThreadRepository)
{
ActivityThreadRepository activityThreadRepository
) {
return new PostActivityUploadToForum(projectForumService, activityThreadRepository, eventBus);
}
@ -953,10 +1044,14 @@ public class CoreConfig {
EventBus eventBus,
NotificationController notificationController,
ForumNotificationRepository forumNotificationRepository,
NotificationService notificationService)
{
return new ForumNotifications(eventBus, notificationController, forumNotificationRepository,
notificationService);
NotificationService notificationService
) {
return new ForumNotifications(
eventBus,
notificationController,
forumNotificationRepository,
notificationService
);
}
@Bean
@ -965,10 +1060,15 @@ public class CoreConfig {
MilestoneServiceImpl milestoneService,
PeerReviewService peerReviewService,
MilestoneActivityTemplateService milestoneActivityTemplateService,
FinalSeminarService finalSeminarService)
{
return new ActivateCompletedMilestonesOnNewProjects(peerReviewService, milestoneActivityTemplateService,
milestoneService, eventBus, finalSeminarService);
FinalSeminarService finalSeminarService
) {
return new ActivateCompletedMilestonesOnNewProjects(
peerReviewService,
milestoneActivityTemplateService,
milestoneService,
eventBus,
finalSeminarService
);
}
@Bean
@ -976,9 +1076,14 @@ public class CoreConfig {
EventBus eventBus,
FinalSeminarServiceImpl finalSeminarService,
NotificationController notificationController,
AuthorRepository authorRepository)
{
return new FinalSeminarCreationSubscribers(authorRepository, finalSeminarService, notificationController, eventBus);
AuthorRepository authorRepository
) {
return new FinalSeminarCreationSubscribers(
authorRepository,
finalSeminarService,
notificationController,
eventBus
);
}
@Bean
@ -989,8 +1094,8 @@ public class CoreConfig {
@Bean
public AddActivityPlanOnProjectStart addActivityPlanOnProjectStart(
ActivityPlanFacade activityPlanFacade,
EventBus eventBus)
{
EventBus eventBus
) {
return new AddActivityPlanOnProjectStart(activityPlanFacade, eventBus);
}
@ -998,8 +1103,8 @@ public class CoreConfig {
public Notifications notifications(
EventBus eventBus,
NotificationController notificationController,
NotificationService notificationService)
{
NotificationService notificationService
) {
return new Notifications(notificationController, notificationService, eventBus);
}
@ -1009,7 +1114,9 @@ public class CoreConfig {
}
@Bean
public NotificationEventServiceImpl notificationEventService(NotificationEventRepository notificationEventRepository) {
public NotificationEventServiceImpl notificationEventService(
NotificationEventRepository notificationEventRepository
) {
return new NotificationEventServiceImpl(notificationEventRepository);
}

File diff suppressed because it is too large Load Diff

@ -53,6 +53,7 @@ import se.su.dsv.scipro.system.UserRepoImpl;
@Configuration(proxyBeanMethods = false)
public class RepositoryConfiguration {
@Bean
public GradingHistoryEventRepositoryImpl gradingHistoryEventRepository(Provider<EntityManager> em) {
return new GradingHistoryEventRepositoryImpl(em);
@ -104,7 +105,9 @@ public class RepositoryConfiguration {
}
@Bean
public FinalSeminarActiveParticipationRepositoryImpl finalSeminarActiveParticipationRepository(Provider<EntityManager> em) {
public FinalSeminarActiveParticipationRepositoryImpl finalSeminarActiveParticipationRepository(
Provider<EntityManager> em
) {
return new FinalSeminarActiveParticipationRepositoryImpl(em);
}

@ -1,5 +1,9 @@
package se.su.dsv.scipro.activityplan;
public enum Action {
NONE, HAND_IN, PEER, FINAL_THESIS, FINAL_SEMINAR
NONE,
HAND_IN,
PEER,
FINAL_THESIS,
FINAL_SEMINAR,
}

@ -1,30 +1,27 @@
package se.su.dsv.scipro.activityplan;
import com.querydsl.core.annotations.QueryInit;
import jakarta.persistence.Basic;
import jakarta.persistence.Table;
import jakarta.persistence.Cacheable;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GenerationType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import se.su.dsv.scipro.checklist.Checklist;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.system.LazyDeletableDomainObject;
import jakarta.persistence.Table;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Date;
import java.util.Objects;
import se.su.dsv.scipro.checklist.Checklist;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.system.LazyDeletableDomainObject;
@Entity
@Table(name = "activity")
@ -59,6 +56,7 @@ public class Activity extends LazyDeletableDomainObject {
@Enumerated(EnumType.STRING)
@Column(name = "action")
private Action action = Action.NONE;
//</editor-fold>
//<editor-fold desc="JPA-mappings of foreign keys in this table (activity) referencing other tables.">
@ -74,6 +72,7 @@ public class Activity extends LazyDeletableDomainObject {
@OneToOne(optional = true, cascade = CascadeType.ALL)
@JoinColumn(name = "upload_file_reference_id", referencedColumnName = "id")
private FileReference fileUpload;
//</editor-fold>
//<editor-fold desc="Constructor">
@ -81,6 +80,7 @@ public class Activity extends LazyDeletableDomainObject {
this.title = "";
this.description = "";
}
//</editor-fold>
//<editor-fold desc="Properties (Getters and Setters)">
@ -156,6 +156,7 @@ public class Activity extends LazyDeletableDomainObject {
public void setFileUpload(FileReference fileUpload) {
this.fileUpload = fileUpload;
}
//</editor-fold>
//<editor-fold desc="Methods Common To All Objects">
@ -164,8 +165,7 @@ public class Activity extends LazyDeletableDomainObject {
if (o == this) return true;
if (!(o instanceof Activity)) return false;
final Activity other = (Activity) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
return (other.canEqual(this) && Objects.equals(this.getId(), other.getId()));
}
@Override
@ -177,16 +177,19 @@ public class Activity extends LazyDeletableDomainObject {
public String toString() {
return "Event: " + getTitle() + "@" + getDate();
}
//</editor-fold>
//<editor-fold desc="Other methods">
protected boolean canEqual(final Object other) {
return other instanceof Activity;
}
//</editor-fold>
//<editor-fold desc="Nested types">
public static class ByDateComparator implements Comparator<Activity>, Serializable {
@Override
public int compare(Activity o1, Activity o2) {
return o1.getDate().compareTo(o2.getDate());
@ -194,6 +197,7 @@ public class Activity extends LazyDeletableDomainObject {
}
public static class Builder implements IActivityPlan, IDate, IName, IDescription, IBuild {
private ActivityPlan activityPlan;
private Date date;
private String name;

@ -3,6 +3,7 @@ package se.su.dsv.scipro.activityplan;
import se.su.dsv.scipro.file.FileDescription;
public class ActivityFileUploadedEvent {
private final Activity activity;
private final FileDescription fileDescription;

@ -11,15 +11,13 @@ import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.DomainObject;
import java.util.Date;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.DomainObject;
@Entity
@Table(name = "activity_plan")
@ -38,17 +36,20 @@ public class ActivityPlan extends DomainObject {
@Basic
@Column(name = "start_date")
private Date startDate;
//</editor-fold>
//<editor-fold desc="JPA-mappings of foreign keys in this table (activity_plan) referencing other tables">
@OneToOne(optional = false)
@JoinColumn(name = "project_id", referencedColumnName = "id")
private Project project;
//</editor-fold>
//<editor-fold desc="JPA-mappings of other tables referencing to this table "activity_plan">
@OneToMany(mappedBy = "activityPlan", cascade = CascadeType.PERSIST, orphanRemoval = true)
private Set<Activity> activities = new TreeSet<>(new Activity.ByDateComparator());
//</editor-fold>
//<editor-fold desc="Properties (Getters and Setters)">
@ -84,6 +85,7 @@ public class ActivityPlan extends DomainObject {
public void setActivities(Set<Activity> activities) {
this.activities = activities;
}
//</editor-fold>
//<editor-fold desc="Methods Common To All Objects">
@ -92,11 +94,13 @@ public class ActivityPlan extends DomainObject {
if (o == this) return true;
if (!(o instanceof ActivityPlan)) return false;
final ActivityPlan other = (ActivityPlan) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId())
&& Objects.equals(this.getActivities(), other.getActivities())
&& Objects.equals(this.getProject(), other.getProject())
&& Objects.equals(this.getStartDate(), other.getStartDate());
return (
other.canEqual(this) &&
Objects.equals(this.getId(), other.getId()) &&
Objects.equals(this.getActivities(), other.getActivities()) &&
Objects.equals(this.getProject(), other.getProject()) &&
Objects.equals(this.getStartDate(), other.getStartDate())
);
}
@Override
@ -106,19 +110,31 @@ public class ActivityPlan extends DomainObject {
@Override
public String toString() {
return "ActivityPlan(id=" + this.getId() + ", activities=" + this.getActivities() + ", project=" +
this.getProject() + ", startDate=" + this.getStartDate() + ")";
return (
"ActivityPlan(id=" +
this.getId() +
", activities=" +
this.getActivities() +
", project=" +
this.getProject() +
", startDate=" +
this.getStartDate() +
")"
);
}
//</editor-fold>
//<editor-fold desc="Other methods">
protected boolean canEqual(final Object other) {
return other instanceof ActivityPlan;
}
//</editor-fold>
//<editor-fold desc="Nested types"
private static class Builder implements IProject, IBuild {
private Project project;
@Override

@ -1,17 +1,15 @@
package se.su.dsv.scipro.activityplan;
import se.su.dsv.scipro.system.Pageable;
import java.util.Date;
import java.util.List;
import se.su.dsv.scipro.checklist.Checklist;
import se.su.dsv.scipro.checklist.ChecklistTemplate;
import se.su.dsv.scipro.file.ProjectFileUpload;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.User;
import java.util.Date;
import java.util.List;
public interface ActivityPlanFacade {
Activity saveActivity(Activity event);
ActivityPlan retrieveActivityPlan(Project p);

@ -1,10 +1,14 @@
package se.su.dsv.scipro.activityplan;
import static com.querydsl.core.types.dsl.Expressions.allOf;
import com.google.common.eventbus.EventBus;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.checklist.Checklist;
import se.su.dsv.scipro.checklist.ChecklistAnswerEnum;
import se.su.dsv.scipro.checklist.ChecklistCategory;
@ -21,14 +25,9 @@ import se.su.dsv.scipro.file.ProjectFileService;
import se.su.dsv.scipro.file.ProjectFileUpload;
import se.su.dsv.scipro.misc.DaysService;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.User;
import jakarta.inject.Inject;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import static com.querydsl.core.types.dsl.Expressions.allOf;
public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
private static final Logger LOGGER = LoggerFactory.getLogger(ActivityPlanFacadeImpl.class);
@ -44,17 +43,27 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
@Inject
ActivityService activityService; // yuck
@Inject
ActivityPlanService activityPlanService; //yuck
@Inject
ActivityPlanTemplateService activityPlanTemplateService;
@Inject
ChecklistService checklistService;
@Inject
ChecklistQuestionRepo checklistQuestionRepo;
@Inject
public ActivityPlanFacadeImpl(final EventBus eventBus, final ProjectFileService projectFileService, ChecklistTemplateService checklistTemplateService, final DaysService daysService, final FileService fileService) {
public ActivityPlanFacadeImpl(
final EventBus eventBus,
final ProjectFileService projectFileService,
ChecklistTemplateService checklistTemplateService,
final DaysService daysService,
final FileService fileService
) {
this.eventBus = eventBus;
this.projectFileService = projectFileService;
this.checklistTemplateService = checklistTemplateService;
@ -71,13 +80,15 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
* @return The newly created event.
*/
@Transactional
private Activity createNewActivity(final ActivityPlan ps,
private Activity createNewActivity(
final ActivityPlan ps,
String name,
String description,
Action action,
final Date date,
final Checklist checklist,
final boolean editable) {
final boolean editable
) {
Activity pse = new Activity();
pse.setActivityPlan(ps);
if (date == null) {
@ -106,8 +117,7 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
if (event.getDescription() == null) {
event.setDescription("");
}
if (event.getId() == null)//Attempt to create a new one if this is a transient entity
{
if (event.getId() == null) { //Attempt to create a new one if this is a transient entity
return createNewActivity(
event.getActivityPlan(),
event.getTitle(),
@ -115,7 +125,8 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
event.getAction(),
event.getDate(),
event.getChecklist(),
event.isEditable());
event.isEditable()
);
}
return activityService.save(event);
}
@ -168,13 +179,19 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
@Override
@Transactional
public void addActivitiesFromTemplate(final Project project, final ActivityPlanTemplate template, final Date startDate) {
public void addActivitiesFromTemplate(
final Project project,
final ActivityPlanTemplate template,
final Date startDate
) {
addActivitiesFromTemplate(retrieveActivityPlan(project), template, startDate);
}
private void addActivitiesFromTemplate(final ActivityPlan schedule,
private void addActivitiesFromTemplate(
final ActivityPlan schedule,
ActivityPlanTemplate template,
final Date startDate) {
final Date startDate
) {
ActivityPlanTemplate reloadedTemplate = activityPlanTemplateService.findOne(template.getId()); //Reload lazily linked entities
int accumulatedOffset = 0;
for (final ActivityTemplate eventTemplate : reloadedTemplate.getActivityTemplates()) {
@ -192,7 +209,8 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
action,
dateForEvent,
createChecklist(schedule.getProject(), checklistTemplate),
true);
true
);
} else {
createNewActivity(schedule, title, desc, action, dateForEvent, null, true);
}
@ -208,7 +226,8 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
final ActivityPlan schedule,
final User user,
final String name,
final String description) {
final String description
) {
Objects.requireNonNull(schedule, "Schedule may not be null");
Objects.requireNonNull(user, "User may not be null");
@ -244,8 +263,7 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
}
private int daysBetween(Date previousEventDate, Date currentEventDate) {
return previousEventDate == null ? 0
: daysService.workDaysBetween(previousEventDate, currentEventDate);
return previousEventDate == null ? 0 : daysService.workDaysBetween(previousEventDate, currentEventDate);
}
@Override
@ -278,7 +296,10 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
final Date dateFrom = from != null ? from : new Date(0);
final Date dateTo = to != null ? to : FAR_IN_THE_FUTURE;
QActivity event = QActivity.activity;
return activityService.findAll(allOf(event.activityPlan.project.eq(project), event.date.after(dateFrom), event.date.before(dateTo)), pageable);
return activityService.findAll(
allOf(event.activityPlan.project.eq(project), event.date.after(dateFrom), event.date.before(dateTo)),
pageable
);
}
@Override
@ -286,7 +307,9 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
final Date dateFrom = from != null ? from : new Date(0);
final Date dateTo = to != null ? to : FAR_IN_THE_FUTURE;
QActivity event = QActivity.activity;
return activityService.count(allOf(event.activityPlan.project.eq(project), event.date.after(dateFrom), event.date.before(dateTo)));
return activityService.count(
allOf(event.activityPlan.project.eq(project), event.date.after(dateFrom), event.date.before(dateTo))
);
}
private void deleteUpload(Activity activity) {
@ -303,7 +326,11 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
@Override
public Checklist createChecklist(Project project, ChecklistTemplate template) {
List<ChecklistCategory> categories = new ArrayList<>(template.getCategories());
Checklist checklist = Checklist.builder().name(template.getName()).project(project).description(template.getDescription()).build();
Checklist checklist = Checklist.builder()
.name(template.getName())
.project(project)
.description(template.getDescription())
.build();
checklist.setCategories(categories);
for (String question : template.getQuestions()) {
ChecklistQuestion clQuestion = new ChecklistQuestion(question, checklist.getNumberOfQuestions());
@ -350,5 +377,4 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
}
return true;
}
}

@ -2,6 +2,4 @@ package se.su.dsv.scipro.activityplan;
import se.su.dsv.scipro.system.GenericService;
public interface ActivityPlanService extends GenericService<ActivityPlan, Long> {
}
public interface ActivityPlanService extends GenericService<ActivityPlan, Long> {}

@ -1,12 +1,12 @@
package se.su.dsv.scipro.activityplan;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.AbstractServiceImpl;
public class ActivityPlanServiceImpl extends AbstractServiceImpl<ActivityPlan, Long> implements ActivityPlanService {
@Inject
public ActivityPlanServiceImpl(Provider<EntityManager> em) {
super(em, ActivityPlan.class, QActivityPlan.activityPlan);

@ -1,11 +1,5 @@
package se.su.dsv.scipro.activityplan;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import jakarta.persistence.Basic;
import jakarta.persistence.Cacheable;
import jakarta.persistence.CascadeType;
@ -19,8 +13,12 @@ import jakarta.persistence.Lob;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderColumn;
import jakarta.persistence.Table;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
@ -46,18 +44,21 @@ public class ActivityPlanTemplate extends DomainObject {
@Column(name = "description")
@Lob
private String description;
//</editor-fold>
//<editor-fold desc="JPA-mappings of foreign keys in this table (activity_plan_template) referencing other tables.">
@ManyToOne(optional = false)
@JoinColumn(name = "creator_user_id", referencedColumnName = "id")
private User creator;
//</editor-fold>
//<editor-fold desc="JPA-mappings of other tables referencing to this table 'activity_plan_template'">
@OneToMany(mappedBy = "activityPlanTemplate", orphanRemoval = true, cascade = CascadeType.ALL)
@OrderColumn(name = "number_in_order")
private List<ActivityTemplate> activityTemplates = new ArrayList<>();
//</editor-fold>
//<editor-fold desc="Properties (Getters and Setters)">
@ -109,6 +110,7 @@ public class ActivityPlanTemplate extends DomainObject {
public void setActivityTemplates(List<ActivityTemplate> activityTemplates) {
this.activityTemplates = new ArrayList<>(activityTemplates);
}
//</editor-fold>
//<editor-fold desc="Methods Common To All Objects">
@ -117,14 +119,16 @@ public class ActivityPlanTemplate extends DomainObject {
if (o == this) return true;
if (!(o instanceof ActivityPlanTemplate)) return false;
final ActivityPlanTemplate other = (ActivityPlanTemplate) o;
return other.canEqual(this)
&& super.equals(o)
&& Objects.equals(this.getId(), other.getId())
&& Objects.equals(this.getActivityTemplates(), other.getActivityTemplates())
&& Objects.equals(this.getCreator(), other.getCreator())
&& Objects.equals(this.getTitle(), other.getTitle())
&& Objects.equals(this.getDescription(), other.getDescription())
&& this.isSysAdminTemplate() == other.isSysAdminTemplate();
return (
other.canEqual(this) &&
super.equals(o) &&
Objects.equals(this.getId(), other.getId()) &&
Objects.equals(this.getActivityTemplates(), other.getActivityTemplates()) &&
Objects.equals(this.getCreator(), other.getCreator()) &&
Objects.equals(this.getTitle(), other.getTitle()) &&
Objects.equals(this.getDescription(), other.getDescription()) &&
this.isSysAdminTemplate() == other.isSysAdminTemplate()
);
}
protected boolean canEqual(final Object other) {
@ -133,15 +137,33 @@ public class ActivityPlanTemplate extends DomainObject {
@Override
public int hashCode() {
return Objects.hash(this.getId(), this.getActivityTemplates(), this.getCreator(), this.getTitle(), this.getDescription(), this.isSysAdminTemplate());
return Objects.hash(
this.getId(),
this.getActivityTemplates(),
this.getCreator(),
this.getTitle(),
this.getDescription(),
this.isSysAdminTemplate()
);
}
@Override
public String toString() {
return "ActivityPlanTemplate(id=" + this.getId() + ", creator=" + this.getCreator() +
", title=" + this.getTitle() + ", description=" + this.getDescription() +
", isSysAdminTemplate=" + this.isSysAdminTemplate() + ")";
return (
"ActivityPlanTemplate(id=" +
this.getId() +
", creator=" +
this.getCreator() +
", title=" +
this.getTitle() +
", description=" +
this.getDescription() +
", isSysAdminTemplate=" +
this.isSysAdminTemplate() +
")"
);
}
//</editor-fold>
//<editor-fold desc="Other methods">

@ -1,18 +1,20 @@
package se.su.dsv.scipro.activityplan;
import se.su.dsv.scipro.system.FilteredService;
import se.su.dsv.scipro.system.GenericService;
import se.su.dsv.scipro.system.User;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import se.su.dsv.scipro.system.FilteredService;
import se.su.dsv.scipro.system.GenericService;
import se.su.dsv.scipro.system.User;
public interface ActivityPlanTemplateService extends GenericService<ActivityPlanTemplate, Long>, FilteredService<ActivityPlanTemplate, Long, ActivityPlanTemplateService.Filter> {
public interface ActivityPlanTemplateService
extends
GenericService<ActivityPlanTemplate, Long>,
FilteredService<ActivityPlanTemplate, Long, ActivityPlanTemplateService.Filter> {
List<ActivityPlanTemplate> findAll(Filter filter);
class Filter implements Serializable {
private String filterString;
private User creator;
@ -37,9 +39,11 @@ public interface ActivityPlanTemplateService extends GenericService<ActivityPlan
if (o == this) return true;
if (!(o instanceof Filter)) return false;
final Filter other = (Filter) o;
return other.canEqual(this)
&& Objects.equals(this.getFilterString(), other.getFilterString())
&& Objects.equals(this.getCreator(), other.getCreator());
return (
other.canEqual(this) &&
Objects.equals(this.getFilterString(), other.getFilterString()) &&
Objects.equals(this.getCreator(), other.getCreator())
);
}
protected boolean canEqual(final Object other) {
@ -53,7 +57,13 @@ public interface ActivityPlanTemplateService extends GenericService<ActivityPlan
@Override
public String toString() {
return "ActivityPlanTemplateService.Filter(filterString=" + this.getFilterString() + ", creator=" + this.getCreator() + ")";
return (
"ActivityPlanTemplateService.Filter(filterString=" +
this.getFilterString() +
", creator=" +
this.getCreator() +
")"
);
}
}
}

@ -2,17 +2,18 @@ package se.su.dsv.scipro.activityplan;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.User;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import java.util.List;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.User;
public class ActivityPlanTemplateServiceImpl
extends AbstractServiceImpl<ActivityPlanTemplate, Long>
implements ActivityPlanTemplateService {
public class ActivityPlanTemplateServiceImpl extends AbstractServiceImpl<ActivityPlanTemplate, Long> implements ActivityPlanTemplateService {
@Inject
public ActivityPlanTemplateServiceImpl(Provider<EntityManager> em) {
super(em, ActivityPlanTemplate.class, QActivityPlanTemplate.activityPlanTemplate);
@ -41,11 +42,14 @@ public class ActivityPlanTemplateServiceImpl extends AbstractServiceImpl<Activit
}
private static Predicate creator(User creator) {
return QActivityPlanTemplate.activityPlanTemplate.isSysAdminTemplate.isTrue().or(QActivityPlanTemplate.activityPlanTemplate.creator.eq(creator));
return QActivityPlanTemplate.activityPlanTemplate.isSysAdminTemplate
.isTrue()
.or(QActivityPlanTemplate.activityPlanTemplate.creator.eq(creator));
}
private static Predicate filterString(String filterString) {
return QActivityPlanTemplate.activityPlanTemplate.title.containsIgnoreCase(filterString)
return QActivityPlanTemplate.activityPlanTemplate.title
.containsIgnoreCase(filterString)
.or(QActivityPlanTemplate.activityPlanTemplate.creator.firstName.containsIgnoreCase(filterString))
.or(QActivityPlanTemplate.activityPlanTemplate.creator.lastName.containsIgnoreCase(filterString));
}

@ -2,6 +2,4 @@ package se.su.dsv.scipro.activityplan;
import se.su.dsv.scipro.system.GenericService;
public interface ActivityService extends GenericService<Activity, Long> {
}
public interface ActivityService extends GenericService<Activity, Long> {}

@ -1,10 +1,9 @@
package se.su.dsv.scipro.activityplan;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.AbstractServiceImpl;
public class ActivityServiceImpl extends AbstractServiceImpl<Activity, Long> implements ActivityService {
@ -12,5 +11,4 @@ public class ActivityServiceImpl extends AbstractServiceImpl<Activity, Long> imp
public ActivityServiceImpl(Provider<EntityManager> em) {
super(em, Activity.class, QActivity.activity);
}
}

@ -1,7 +1,5 @@
package se.su.dsv.scipro.activityplan;
import java.util.Objects;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
@ -14,7 +12,7 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.Lob;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.util.Objects;
import se.su.dsv.scipro.checklist.ChecklistTemplate;
import se.su.dsv.scipro.system.DomainObject;
@ -48,6 +46,7 @@ public class ActivityTemplate extends DomainObject {
@Basic
@Column(name = "number_in_order", nullable = false)
private int numberInOrder = Integer.MAX_VALUE;
//</editor-fold>
//<editor-fold desc="JPA-mappings of foreign keys in this table (activity_template) referencing other tables.">
@ -58,15 +57,16 @@ public class ActivityTemplate extends DomainObject {
@ManyToOne(optional = true)
@JoinColumn(name = "checklist_template_id", referencedColumnName = "id")
private ChecklistTemplate checklistTemplate;
//</editor-fold>
//<editor-fold desc="Constructors">
public ActivityTemplate() {
}
public ActivityTemplate() {}
public ActivityTemplate(int daysOffset) {
this.daysOffset = daysOffset;
}
//</editor-fold>
//<editor-fold desc="Properties (Getters and Setters">
@ -134,6 +134,7 @@ public class ActivityTemplate extends DomainObject {
public void setChecklistTemplate(ChecklistTemplate checklistTemplate) {
this.checklistTemplate = checklistTemplate;
}
//</editor-fold>
//<editor-fold desc="Methods Common To All Objects">
@ -142,8 +143,7 @@ public class ActivityTemplate extends DomainObject {
if (o == this) return true;
if (!(o instanceof ActivityTemplate)) return false;
final ActivityTemplate other = (ActivityTemplate) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
return (other.canEqual(this) && Objects.equals(this.getId(), other.getId()));
}
@Override
@ -153,12 +153,27 @@ public class ActivityTemplate extends DomainObject {
@Override
public String toString() {
return "ActivityTemplate(id=" + this.getId() + ", title=" + this.getTitle() +
", description=" + this.getDescription() + ", activityPlanTemplate=" +
this.getActivityPlanTemplate() + ", daysOffset=" + this.getDaysOffset() + ", action=" +
this.getAction() + ", numberInOrder=" + this.getNumberInOrder() + ", checklistTemplate=" +
this.getChecklistTemplate() + ")";
return (
"ActivityTemplate(id=" +
this.getId() +
", title=" +
this.getTitle() +
", description=" +
this.getDescription() +
", activityPlanTemplate=" +
this.getActivityPlanTemplate() +
", daysOffset=" +
this.getDaysOffset() +
", action=" +
this.getAction() +
", numberInOrder=" +
this.getNumberInOrder() +
", checklistTemplate=" +
this.getChecklistTemplate() +
")"
);
}
//</editor-fold>
//<editor-fold desc="Other methods">

@ -18,16 +18,15 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapKeyJoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
@Entity
@Table(name = "checklist")
@ -54,15 +53,19 @@ public class Checklist extends DomainObject {
private Project project;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "checklist_checklist_question",
@JoinTable(
name = "checklist_checklist_question",
joinColumns = @JoinColumn(name = "checklist_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "checklist_question_id", referencedColumnName = "id"))
inverseJoinColumns = @JoinColumn(name = "checklist_question_id", referencedColumnName = "id")
)
private List<ChecklistQuestion> questions = new ArrayList<>();
@ManyToMany
@JoinTable(name = "checklist_checklist_category",
@JoinTable(
name = "checklist_checklist_category",
joinColumns = @JoinColumn(name = "checklist_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "checklist_category_id", referencedColumnName = "id"))
inverseJoinColumns = @JoinColumn(name = "checklist_category_id", referencedColumnName = "id")
)
private List<se.su.dsv.scipro.checklist.ChecklistCategory> categories = new ArrayList<>();
@ElementCollection(fetch = FetchType.EAGER)
@ -72,8 +75,7 @@ public class Checklist extends DomainObject {
@MapKeyJoinColumn(name = "user_id")
private Map<User, Date> userLastOpenDate = new HashMap<>();
protected Checklist() {
}
protected Checklist() {}
public int getNumberOfQuestions() {
return questions.size();
@ -148,7 +150,23 @@ public class Checklist extends DomainObject {
@Override
public String toString() {
return "Checklist(id=" + this.getId() + ", name=" + this.getName() + ", description=" + this.getDescription() + ", project=" + this.getProject() + ", questions=" + this.getQuestions() + ", categories=" + this.getCategories() + ", userLastOpenDate=" + this.getUserLastOpenDate() + ")";
return (
"Checklist(id=" +
this.getId() +
", name=" +
this.getName() +
", description=" +
this.getDescription() +
", project=" +
this.getProject() +
", questions=" +
this.getQuestions() +
", categories=" +
this.getCategories() +
", userLastOpenDate=" +
this.getUserLastOpenDate() +
")"
);
}
@Override
@ -156,8 +174,7 @@ public class Checklist extends DomainObject {
if (o == this) return true;
if (!(o instanceof Checklist)) return false;
final Checklist other = (Checklist) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
return (other.canEqual(this) && Objects.equals(this.getId(), other.getId()));
}
protected boolean canEqual(final Object other) {
@ -170,6 +187,7 @@ public class Checklist extends DomainObject {
}
private static class Builder implements IName, IProject, IBuild {
private final Checklist instance = new Checklist();
@Override
@ -204,12 +222,9 @@ public class Checklist extends DomainObject {
IBuild project(Project project);
}
public interface IBuild {
IBuild description(String description);
Checklist build();
}
}

@ -1,7 +1,5 @@
package se.su.dsv.scipro.checklist;
import java.util.Objects;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
@ -14,13 +12,14 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.Lob;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.util.Objects;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
@Entity
@Table(name = "checklist_answer")
public class ChecklistAnswer extends DomainObject {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@ -49,8 +48,7 @@ public class ChecklistAnswer extends DomainObject {
// ----------------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------------
protected ChecklistAnswer() {
}
protected ChecklistAnswer() {}
public ChecklistAnswer(User user) {
this(user, null);
@ -105,8 +103,7 @@ public class ChecklistAnswer extends DomainObject {
if (o == this) return true;
if (!(o instanceof ChecklistAnswer)) return false;
final ChecklistAnswer other = (ChecklistAnswer) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
return (other.canEqual(this) && Objects.equals(this.getId(), other.getId()));
}
@Override
@ -116,8 +113,17 @@ public class ChecklistAnswer extends DomainObject {
@Override
public String toString() {
return "ChecklistAnswer(id=" + this.getId() + ", answer=" + this.getAnswer() + ", user=" + this.getUser() +
", comment=" + this.getComment() + ")";
return (
"ChecklistAnswer(id=" +
this.getId() +
", answer=" +
this.getAnswer() +
", user=" +
this.getUser() +
", comment=" +
this.getComment() +
")"
);
}
// ----------------------------------------------------------------------------------

@ -5,5 +5,5 @@ public enum ChecklistAnswerEnum {
GREEN,
YELLOW,
NOT_APPLICABLE,
NO_ANSWER
NO_ANSWER,
}

@ -2,6 +2,4 @@ package se.su.dsv.scipro.checklist;
import se.su.dsv.scipro.system.GenericService;
public interface ChecklistAnswerService extends GenericService<ChecklistAnswer, Long> {
}
public interface ChecklistAnswerService extends GenericService<ChecklistAnswer, Long> {}

@ -1,12 +1,13 @@
package se.su.dsv.scipro.checklist;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.AbstractServiceImpl;
public class ChecklistAnswerServiceImpl extends AbstractServiceImpl<ChecklistAnswer, Long> implements ChecklistAnswerService {
public class ChecklistAnswerServiceImpl
extends AbstractServiceImpl<ChecklistAnswer, Long>
implements ChecklistAnswerService {
@Inject
public ChecklistAnswerServiceImpl(Provider<EntityManager> em) {

@ -1,7 +1,5 @@
package se.su.dsv.scipro.checklist;
import java.util.Objects;
import jakarta.persistence.Cacheable;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
@ -9,13 +7,14 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.Objects;
import se.su.dsv.scipro.system.DomainObject;
@Entity
@Table(name = "checklist_category")
@Cacheable(true)
public class ChecklistCategory extends DomainObject {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ -23,8 +22,7 @@ public class ChecklistCategory extends DomainObject {
@Column(name = "category_name", unique = true)
private String categoryName;
protected ChecklistCategory() {
}
protected ChecklistCategory() {}
public ChecklistCategory(final String name) {
categoryName = name;
@ -49,7 +47,7 @@ public class ChecklistCategory extends DomainObject {
@Override
public String toString() {
return "ChecklistCategory(id=" + this.getId() + ", categoryName=" + this.getCategoryName() + ")";
return ("ChecklistCategory(id=" + this.getId() + ", categoryName=" + this.getCategoryName() + ")");
}
@Override
@ -57,8 +55,7 @@ public class ChecklistCategory extends DomainObject {
if (o == this) return true;
if (!(o instanceof ChecklistCategory)) return false;
final ChecklistCategory other = (ChecklistCategory) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
return (other.canEqual(this) && Objects.equals(this.getId(), other.getId()));
}
protected boolean canEqual(final Object other) {

@ -4,8 +4,6 @@ import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
@Transactional
public interface ChecklistCategoryRepo extends JpaRepository<ChecklistCategory, Long>, QueryDslPredicateExecutor<ChecklistCategory> {
}
public interface ChecklistCategoryRepo
extends JpaRepository<ChecklistCategory, Long>, QueryDslPredicateExecutor<ChecklistCategory> {}

@ -1,12 +1,12 @@
package se.su.dsv.scipro.checklist;
import se.su.dsv.scipro.system.GenericRepo;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.GenericRepo;
public class ChecklistCategoryRepoImpl extends GenericRepo<ChecklistCategory, Long> implements ChecklistCategoryRepo {
@Inject
public ChecklistCategoryRepoImpl(Provider<EntityManager> em) {
super(em, ChecklistCategory.class, QChecklistCategory.checklistCategory);

@ -1,9 +1,5 @@
package se.su.dsv.scipro.checklist;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import jakarta.persistence.Basic;
import jakarta.persistence.Cacheable;
import jakarta.persistence.CascadeType;
@ -17,7 +13,9 @@ import jakarta.persistence.JoinTable;
import jakarta.persistence.Lob;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
@ -25,6 +23,7 @@ import se.su.dsv.scipro.system.User;
@Table(name = "checklist_question")
@Cacheable(true)
public class ChecklistQuestion extends DomainObject {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ -41,11 +40,11 @@ public class ChecklistQuestion extends DomainObject {
@JoinTable(
name = "checklist_question_checklist_answer",
joinColumns = @JoinColumn(name = "checklist_question_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "checklist_answer_id", referencedColumnName = "id"))
inverseJoinColumns = @JoinColumn(name = "checklist_answer_id", referencedColumnName = "id")
)
private List<ChecklistAnswer> answers = new ArrayList<>();
protected ChecklistQuestion() {
}
protected ChecklistQuestion() {}
public ChecklistQuestion(String question, int questionNumber) {
this.question = question;
@ -104,7 +103,17 @@ public class ChecklistQuestion extends DomainObject {
@Override
public String toString() {
return "ChecklistQuestion(id=" + this.getId() + ", question=" + this.getQuestion() + ", questionNumber=" + this.getQuestionNumber() + ", answers=" + this.getAnswers() + ")";
return (
"ChecklistQuestion(id=" +
this.getId() +
", question=" +
this.getQuestion() +
", questionNumber=" +
this.getQuestionNumber() +
", answers=" +
this.getAnswers() +
")"
);
}
@Override
@ -112,8 +121,7 @@ public class ChecklistQuestion extends DomainObject {
if (o == this) return true;
if (!(o instanceof ChecklistQuestion)) return false;
final ChecklistQuestion other = (ChecklistQuestion) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
return (other.canEqual(this) && Objects.equals(this.getId(), other.getId()));
}
protected boolean canEqual(final Object other) {

@ -4,7 +4,6 @@ import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
@Transactional
public interface ChecklistQuestionRepo extends JpaRepository<ChecklistQuestion, Long>, QueryDslPredicateExecutor<ChecklistQuestion> {
}
public interface ChecklistQuestionRepo
extends JpaRepository<ChecklistQuestion, Long>, QueryDslPredicateExecutor<ChecklistQuestion> {}

@ -1,12 +1,12 @@
package se.su.dsv.scipro.checklist;
import se.su.dsv.scipro.system.GenericRepo;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.GenericRepo;
public class ChecklistQuestionRepoImpl extends GenericRepo<ChecklistQuestion, Long> implements ChecklistQuestionRepo {
@Inject
public ChecklistQuestionRepoImpl(Provider<EntityManager> em) {
super(em, ChecklistQuestion.class, QChecklistQuestion.checklistQuestion);

@ -5,7 +5,6 @@ import se.su.dsv.scipro.system.GenericService;
import se.su.dsv.scipro.system.User;
public interface ChecklistService extends GenericService<Checklist, Long> {
Long countAnswers(Project project, ChecklistAnswerEnum answer);
Long countUnanswered(Project project);

@ -1,19 +1,18 @@
package se.su.dsv.scipro.checklist;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.activityplan.QActivity;
import se.su.dsv.scipro.activityplan.QActivityPlan;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import java.util.Date;
import se.su.dsv.scipro.activityplan.QActivity;
import se.su.dsv.scipro.activityplan.QActivityPlan;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.User;
import java.util.Date;
public class ChecklistServiceImpl extends AbstractServiceImpl<Checklist, Long> implements ChecklistService {
@Inject
public ChecklistServiceImpl(Provider<EntityManager> em) {
super(em, Checklist.class, QChecklist.checklist);
@ -26,9 +25,7 @@ public class ChecklistServiceImpl extends AbstractServiceImpl<Checklist, Long> i
.join(QActivityPlan.activityPlan.activities, QActivity.activity)
.join(QActivity.activity.checklist.questions, QChecklistQuestion.checklistQuestion)
.join(QChecklistQuestion.checklistQuestion.answers, QChecklistAnswer.checklistAnswer)
.where(
QActivityPlan.activityPlan.project.eq(project),
QChecklistAnswer.checklistAnswer.answer.eq(answer))
.where(QActivityPlan.activityPlan.project.eq(project), QChecklistAnswer.checklistAnswer.answer.eq(answer))
.fetchFirst();
}

@ -13,19 +13,19 @@ import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
@Entity
@Table(name = "checklist_template")
public class ChecklistTemplate extends DomainObject {
public static final int MIN_TITLE_LENGTH = 3;
public static final int DEFAULT_TEMPLATE_NUMBER = 999;
@ -46,8 +46,7 @@ public class ChecklistTemplate extends DomainObject {
private int templateNumber = DEFAULT_TEMPLATE_NUMBER;
@ElementCollection
@CollectionTable(name = "checklist_template_question",
joinColumns = @JoinColumn(name = "checklist_template_id"))
@CollectionTable(name = "checklist_template_question", joinColumns = @JoinColumn(name = "checklist_template_id"))
@Column(name = "question")
private List<String> questions = new ArrayList<>(1);
@ -56,20 +55,22 @@ public class ChecklistTemplate extends DomainObject {
private User creator;
@ManyToMany
@JoinTable(name = "checklist_template_checklist_category",
@JoinTable(
name = "checklist_template_checklist_category",
joinColumns = @JoinColumn(name = "checklist_template_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "checklist_category_id", referencedColumnName = "id"))
inverseJoinColumns = @JoinColumn(name = "checklist_category_id", referencedColumnName = "id")
)
private List<ChecklistCategory> categories = new ArrayList<>();
@ManyToMany
@JoinTable(name = "checklist_template_project_type",
@JoinTable(
name = "checklist_template_project_type",
joinColumns = { @JoinColumn(name = "checklist_template_id") },
inverseJoinColumns = {@JoinColumn(name = "project_type_id")})
inverseJoinColumns = { @JoinColumn(name = "project_type_id") }
)
private Collection<ProjectType> projectTypes = new HashSet<>();
public ChecklistTemplate() {
}
public ChecklistTemplate() {}
public ChecklistTemplate(String name, User creator) {
this.name = name;
@ -151,7 +152,25 @@ public class ChecklistTemplate extends DomainObject {
@Override
public String toString() {
return "ChecklistTemplate(id=" + this.getId() + ", name=" + this.getName() + ", description=" + this.getDescription() + ", templateNumber=" + this.getTemplateNumber() + ", questions=" + this.getQuestions() + ", creator=" + this.getCreator() + ", categories=" + this.getCategories() + ", projectTypes=" + this.getProjectTypes() + ")";
return (
"ChecklistTemplate(id=" +
this.getId() +
", name=" +
this.getName() +
", description=" +
this.getDescription() +
", templateNumber=" +
this.getTemplateNumber() +
", questions=" +
this.getQuestions() +
", creator=" +
this.getCreator() +
", categories=" +
this.getCategories() +
", projectTypes=" +
this.getProjectTypes() +
")"
);
}
@Override
@ -159,8 +178,7 @@ public class ChecklistTemplate extends DomainObject {
if (o == this) return true;
if (!(o instanceof ChecklistTemplate)) return false;
final ChecklistTemplate other = (ChecklistTemplate) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
return (other.canEqual(this) && Objects.equals(this.getId(), other.getId()));
}
protected boolean canEqual(final Object other) {

@ -1,12 +1,12 @@
package se.su.dsv.scipro.checklist;
import java.util.List;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.FilteredService;
import se.su.dsv.scipro.system.GenericService;
import java.util.List;
public interface ChecklistTemplateService extends GenericService<ChecklistTemplate, Long>, FilteredService<ChecklistTemplate, Long, String> {
public interface ChecklistTemplateService
extends GenericService<ChecklistTemplate, Long>, FilteredService<ChecklistTemplate, Long, String> {
void upChecklistTemplate(ChecklistTemplate checklistTemplate);
void downChecklistTemplate(ChecklistTemplate checklistTemplate);
void safeDeleteChecklistTemplate(ChecklistTemplate checklistTemplate);

@ -1,19 +1,20 @@
package se.su.dsv.scipro.checklist;
import jakarta.transaction.Transactional;
import com.querydsl.core.types.dsl.BooleanExpression;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import java.util.List;
import static com.querydsl.core.types.dsl.Expressions.allOf;
public class ChecklistTemplateServiceImpl extends AbstractServiceImpl<ChecklistTemplate,Long> implements ChecklistTemplateService {
import com.querydsl.core.types.dsl.BooleanExpression;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import java.util.List;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.Pageable;
public class ChecklistTemplateServiceImpl
extends AbstractServiceImpl<ChecklistTemplate, Long>
implements ChecklistTemplateService {
public static final String PEER = "Peer";
@ -65,7 +66,9 @@ public class ChecklistTemplateServiceImpl extends AbstractServiceImpl<ChecklistT
@Transactional
@Override
public void safeDeleteChecklistTemplate(ChecklistTemplate checklistTemplate) {
for (ChecklistTemplate clt : findAll(QChecklistTemplate.checklistTemplate.templateNumber.gt(checklistTemplate.getTemplateNumber()))) {
for (ChecklistTemplate clt : findAll(
QChecklistTemplate.checklistTemplate.templateNumber.gt(checklistTemplate.getTemplateNumber())
)) {
clt.setTemplateNumber(clt.getTemplateNumber() - 1);
}
delete(checklistTemplate);
@ -73,10 +76,12 @@ public class ChecklistTemplateServiceImpl extends AbstractServiceImpl<ChecklistT
@Override
public List<ChecklistTemplate> findPeerRequestChecklists(final Project project) {
return findAll(allOf(
return findAll(
allOf(
QChecklistTemplate.checklistTemplate.projectTypes.any().eq(project.getProjectType()),
QChecklistTemplate.checklistTemplate.categories.any().categoryName.eq(PEER)
));
)
);
}
@Override
@ -90,7 +95,9 @@ public class ChecklistTemplateServiceImpl extends AbstractServiceImpl<ChecklistT
}
public static BooleanExpression filterStringIsCreatorName(String filterString) {
return QChecklistTemplate.checklistTemplate.creator.firstName.contains(filterString).or(QChecklistTemplate.checklistTemplate.creator.lastName.contains(filterString));
return QChecklistTemplate.checklistTemplate.creator.firstName
.contains(filterString)
.or(QChecklistTemplate.checklistTemplate.creator.lastName.contains(filterString));
}
public static BooleanExpression filterStringIsChecklistTemplateName(String filterString) {

@ -5,5 +5,4 @@ public class ExternalImportException extends RuntimeException {
public ExternalImportException(Throwable e) {
super(e);
}
}

@ -1,13 +1,12 @@
package se.su.dsv.scipro.daisyExternal.http;
import jakarta.ws.rs.core.Response;
import se.su.dsv.scipro.io.dto.*;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import se.su.dsv.scipro.io.dto.*;
public interface DaisyAPI {
Set<ProjectParticipant> getContributors(Integer projectId);

@ -1,5 +1,9 @@
package se.su.dsv.scipro.daisyExternal.http;
import static jakarta.ws.rs.client.Entity.xml;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.client.Client;
@ -10,16 +14,11 @@ import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.GenericType;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import se.su.dsv.scipro.io.dto.*;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import static jakarta.ws.rs.client.Entity.xml;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import se.su.dsv.scipro.io.dto.*;
public class DaisyAPIImpl implements DaisyAPI {
@ -46,10 +45,10 @@ public class DaisyAPIImpl implements DaisyAPI {
public DaisyAPIImpl(
@Named("daisy.api.url") final String baseUrl,
@Named("daisy.api.username") final String user,
@Named("daisy.api.password") final String password) {
@Named("daisy.api.password") final String password
) {
this.baseUrl = baseUrl;
this.client = ClientBuilder.newClient()
.register(HttpAuthenticationFeature.basic(user, password));
this.client = ClientBuilder.newClient().register(HttpAuthenticationFeature.basic(user, password));
this.objectFactory = new ObjectFactory();
}
@ -59,8 +58,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(String.valueOf(projectId))
.path(CONTRIBUTOR)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
}
@Override
@ -69,8 +67,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(String.valueOf(projectId))
.path(AUTHOR)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
}
@Override
@ -79,8 +76,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(String.valueOf(personId))
.path(THESES)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
}
@Override
@ -89,19 +85,16 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(String.valueOf(unitId))
.path(SUBUNITS)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
}
@Override
public Set<UserName> getUsernames(Integer personId) {
return person()
.path(String.valueOf(personId))
.path(USERNAMES)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
}
@Override
@ -110,8 +103,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(String.valueOf(personId))
.path(RESEARCH_AREAS)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
}
@Override
@ -120,8 +112,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(String.valueOf(unitId))
.path(SUPERVISORS)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
}
@Override
@ -130,9 +121,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(String.valueOf(id))
.request(MediaType.APPLICATION_XML_TYPE)
.get(Response.class);
return response.getStatus() == 200
? Optional.of(response.readEntity(Person.class))
: Optional.empty();
return response.getStatus() == 200 ? Optional.of(response.readEntity(Person.class)) : Optional.empty();
}
@Override
@ -142,9 +131,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(userName)
.request(MediaType.APPLICATION_XML_TYPE)
.get(Response.class);
return response.getStatus() == 200
? Optional.of(response.readEntity(Person.class))
: Optional.empty();
return response.getStatus() == 200 ? Optional.of(response.readEntity(Person.class)) : Optional.empty();
}
@Override
@ -168,9 +155,7 @@ public class DaisyAPIImpl implements DaisyAPI {
@Override
public Response createProject(ThesisToBeCreated project) {
return thesis()
.request(MediaType.APPLICATION_XML_TYPE)
.post(xml(project));
return thesis().request(MediaType.APPLICATION_XML_TYPE).post(xml(project));
}
@Override
@ -184,26 +169,17 @@ public class DaisyAPIImpl implements DaisyAPI {
@Override
public Response deleteProject(Integer projectId) {
return thesis()
.path(String.valueOf(projectId))
.request(MediaType.APPLICATION_XML_TYPE)
.delete();
return thesis().path(String.valueOf(projectId)).request(MediaType.APPLICATION_XML_TYPE).delete();
}
@Override
public Response getStudent(Integer id) {
return student()
.path(String.valueOf(id))
.request(MediaType.APPLICATION_XML_TYPE)
.get();
return student().path(String.valueOf(id)).request(MediaType.APPLICATION_XML_TYPE).get();
}
@Override
public Program getProgram(Integer id) {
return program()
.path(String.valueOf(id))
.request(MediaType.APPLICATION_XML_TYPE)
.get(Program.class);
return program().path(String.valueOf(id)).request(MediaType.APPLICATION_XML_TYPE).get(Program.class);
}
@Override
@ -212,17 +188,12 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(String.valueOf(projectIdentifier))
.request(MediaType.APPLICATION_XML_TYPE)
.get(Response.class);
return response.getStatus() == 200
? Optional.of(response.readEntity(Thesis.class))
: Optional.empty();
return response.getStatus() == 200 ? Optional.of(response.readEntity(Thesis.class)) : Optional.empty();
}
@Override
public void updateThesis(final Integer id, ThesisToBeUpdated thesis) {
thesis()
.path(String.valueOf(id))
.request()
.put(xml(thesis));
thesis().path(String.valueOf(id)).request().put(xml(thesis));
}
@Override
@ -233,9 +204,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(String.valueOf(authorId))
.request(MediaType.APPLICATION_XML_TYPE)
.get();
return response.getStatus() == 200
? Optional.ofNullable(response.readEntity(String.class))
: Optional.empty();
return response.getStatus() == 200 ? Optional.ofNullable(response.readEntity(String.class)) : Optional.empty();
}
@Override
@ -243,8 +212,7 @@ public class DaisyAPIImpl implements DaisyAPI {
return person()
.queryParam("personnummer", personnummer)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
}
@Override
@ -333,8 +301,7 @@ public class DaisyAPIImpl implements DaisyAPI {
return program()
.queryParam("responsibleDepartment", responsibleDepartmentId)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
}
@Override
@ -344,8 +311,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.path("admissions")
.queryParam("admissionSemester", admissionSemester.getId())
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
}
@Override
@ -357,8 +323,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.queryParam("since", sinceParameter)
// must be XML due to api date-formatting in json
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
}
@Override
@ -368,8 +333,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(Integer.toString(studentId))
.path("programAdmissions")
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
} catch (NotFoundException ignored) {
return Collections.emptyList();
}
@ -382,8 +346,7 @@ public class DaisyAPIImpl implements DaisyAPI {
.path(Integer.toString(studentId))
.path("courseRegistrations")
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.get(new GenericType<>() {});
} catch (NotFoundException ignored) {
return Collections.emptyList();
}
@ -400,7 +363,8 @@ public class DaisyAPIImpl implements DaisyAPI {
@Override
public OrganisationalUnit orgunit(final int unitId) {
return () -> target()
return () ->
target()
.path("orgunit")
.path(Integer.toString(unitId))
.path("researchAreas")
@ -444,37 +408,30 @@ public class DaisyAPIImpl implements DaisyAPI {
}
private WebTarget program() {
return target()
.path(PROGRAM);
return target().path(PROGRAM);
}
private WebTarget student() {
return target()
.path(STUDENT);
return target().path(STUDENT);
}
private WebTarget thesis() {
return target()
.path(THESIS);
return target().path(THESIS);
}
private WebTarget units() {
return target()
.path(ORGUNIT);
return target().path(ORGUNIT);
}
private WebTarget person() {
return target()
.path(PERSON);
return target().path(PERSON);
}
private WebTarget course() {
return target()
.path(COURSE);
return target().path(COURSE);
}
private WebTarget target() {
return client
.target(baseUrl);
return client.target(baseUrl);
}
}

@ -1,8 +1,7 @@
package se.su.dsv.scipro.daisyExternal.http;
import se.su.dsv.scipro.io.dto.ResearchArea;
import java.util.List;
import se.su.dsv.scipro.io.dto.ResearchArea;
public interface OrganisationalUnit {
List<ResearchArea> getResearchAreas();

@ -6,23 +6,38 @@ import java.util.function.Supplier;
public abstract class PhotoResult {
public abstract <X> X fold(final Supplier<X> missing, final Supplier<X> forbidden, final Function<InputStream, X> found);
public abstract <X> X fold(
final Supplier<X> missing,
final Supplier<X> forbidden,
final Function<InputStream, X> found
);
public static class Missing extends PhotoResult {
@Override
public <X> X fold(final Supplier<X> missing, final Supplier<X> forbidden, final Function<InputStream, X> found) {
public <X> X fold(
final Supplier<X> missing,
final Supplier<X> forbidden,
final Function<InputStream, X> found
) {
return missing.get();
}
}
static class Forbidden extends PhotoResult {
@Override
public <X> X fold(final Supplier<X> missing, final Supplier<X> forbidden, final Function<InputStream, X> found) {
public <X> X fold(
final Supplier<X> missing,
final Supplier<X> forbidden,
final Function<InputStream, X> found
) {
return forbidden.get();
}
}
static class Found extends PhotoResult {
private final InputStream photo;
Found(final InputStream photo) {
@ -30,9 +45,12 @@ public abstract class PhotoResult {
}
@Override
public <X> X fold(final Supplier<X> missing, final Supplier<X> forbidden, final Function<InputStream, X> found) {
public <X> X fold(
final Supplier<X> missing,
final Supplier<X> forbidden,
final Function<InputStream, X> found
) {
return found.apply(photo);
}
}
}

@ -1,6 +1,7 @@
package se.su.dsv.scipro.daisyExternal.http;
public abstract class Semester {
public static Semester spring(int year) {
return new Spring(year);
}
@ -17,6 +18,7 @@ public abstract class Semester {
public abstract String toString();
private static final class Spring extends Semester {
private final int year;
public Spring(final int year) {
@ -35,6 +37,7 @@ public abstract class Semester {
}
private static final class Autumn extends Semester {
private final int year;
public Autumn(final int year) {

@ -1,11 +1,11 @@
package se.su.dsv.scipro.data.dataobjects;
import se.su.dsv.scipro.system.User;
import java.io.Serializable;
import java.util.Objects;
import se.su.dsv.scipro.system.User;
public class Member implements Serializable {
private final User user;
private final Type type;
@ -75,7 +75,7 @@ public class Member implements Serializable {
public String toString() {
return "Individual milestone";
}
}
},
}
public Member(User user, Type type) {
@ -96,9 +96,11 @@ public class Member implements Serializable {
if (o == this) return true;
if (!(o instanceof Member)) return false;
final Member other = (Member) o;
return other.canEqual(this)
&& Objects.equals(this.getUser(), other.getUser())
&& Objects.equals(this.getType(), other.getType());
return (
other.canEqual(this) &&
Objects.equals(this.getUser(), other.getUser()) &&
Objects.equals(this.getType(), other.getType())
);
}
protected boolean canEqual(final Object other) {
@ -112,6 +114,6 @@ public class Member implements Serializable {
@Override
public String toString() {
return "Member(user=" + this.getUser() + ", type=" + this.getType() + ")";
return ("Member(user=" + this.getUser() + ", type=" + this.getType() + ")");
}
}

@ -1,8 +1,9 @@
package se.su.dsv.scipro.data.enums;
public enum DateStyle {
DATETIME("yyyy-MM-dd HH:mm"), DATE("yyyy-MM-dd"), TIME("HH:mm");
DATETIME("yyyy-MM-dd HH:mm"),
DATE("yyyy-MM-dd"),
TIME("HH:mm");
private final String format;

@ -22,6 +22,4 @@ public enum MailChoice {
public String toString() {
return asString;
}
}

@ -1,5 +1,8 @@
package se.su.dsv.scipro.data.facade;
import jakarta.inject.Inject;
import java.io.Serializable;
import java.util.*;
import se.su.dsv.scipro.data.enums.MailChoice;
import se.su.dsv.scipro.generalsystemsettings.GeneralSystemSettingsService;
import se.su.dsv.scipro.mail.EmailRecipient;
@ -15,16 +18,14 @@ import se.su.dsv.scipro.project.ProjectStatus;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
import jakarta.inject.Inject;
import java.io.Serializable;
import java.util.*;
public class MailFacade implements Serializable {
@Inject
private ProjectService projectService;
@Inject
private IdeaService ideaService;
@Inject
private GeneralSystemSettingsService generalSystemSettingsService;
@ -38,7 +39,12 @@ public class MailFacade implements Serializable {
return supervisorsFromProjects(filter);
}
private Set<Recipient> addProjectCoSupervisors(ProjectStatus ps, Set<ProjectType> pc, Date startDate, Date endDate) {
private Set<Recipient> addProjectCoSupervisors(
ProjectStatus ps,
Set<ProjectType> pc,
Date startDate,
Date endDate
) {
final ProjectService.Filter filter = setProjectParams(ps, pc, startDate, endDate);
return coSupervisorsFromProjects(filter);
}
@ -48,7 +54,12 @@ public class MailFacade implements Serializable {
return reviewersFromProjects(filter);
}
private ProjectService.Filter setProjectParams(ProjectStatus status, Set<ProjectType> pc, Date startDate, Date endDate) {
private ProjectService.Filter setProjectParams(
ProjectStatus status,
Set<ProjectType> pc,
Date startDate,
Date endDate
) {
final ProjectService.Filter projectParams = new ProjectService.Filter();
if (status != null) {
projectParams.setStatuses(new HashSet<>(Collections.singletonList(status)));
@ -112,11 +123,12 @@ public class MailFacade implements Serializable {
}
private Set<Recipient> addThesisSupport() {
String thesisSupportMail = generalSystemSettingsService.getGeneralSystemSettingsInstance().getThesisSupportMail();
String thesisSupportMail = generalSystemSettingsService
.getGeneralSystemSettingsInstance()
.getThesisSupportMail();
if (thesisSupportMail != null) {
return Collections.singleton(new EmailRecipient(thesisSupportMail));
}
else {
} else {
return Collections.emptySet();
}
}
@ -140,23 +152,53 @@ public class MailFacade implements Serializable {
allFollowers.addAll(addProjectCoSupervisors(ProjectStatus.ACTIVE, pc, startDate, endDate));
return allFollowers;
case AUTHORS_MATCHED_IDEA:
IdeaService.Filter matchedFilter = setIdeaParams(Arrays.asList(Idea.Status.COMPLETED, Idea.Status.MATCHED), pc, startDate, endDate, null);
IdeaService.Filter matchedFilter = setIdeaParams(
Arrays.asList(Idea.Status.COMPLETED, Idea.Status.MATCHED),
pc,
startDate,
endDate,
null
);
return authorsFromIdeas(matchedFilter);
case AUTHORS_SUBMITTED_IDEA:
IdeaService.Filter submittedFilter = setIdeaParams(null, pc, startDate, endDate, Collections.singletonList(Type.STUDENT));
IdeaService.Filter submittedFilter = setIdeaParams(
null,
pc,
startDate,
endDate,
Collections.singletonList(Type.STUDENT)
);
return authorsFromIdeas(submittedFilter);
case SUPERVISORS_MATCHED_IDEA:
IdeaService.Filter supervisorMatchedFilter = setIdeaParams(Arrays.asList(Idea.Status.COMPLETED, Idea.Status.MATCHED), pc, startDate, endDate, null);
IdeaService.Filter supervisorMatchedFilter = setIdeaParams(
Arrays.asList(Idea.Status.COMPLETED, Idea.Status.MATCHED),
pc,
startDate,
endDate,
null
);
return supervisorsFromIdeas(supervisorMatchedFilter);
case SUPERVISORS_SUBMITTED_IDEA:
IdeaService.Filter supervisorSubmittedFilter = setIdeaParams(null, pc, startDate, endDate, Collections.singletonList(Type.SUPERVISOR));
IdeaService.Filter supervisorSubmittedFilter = setIdeaParams(
null,
pc,
startDate,
endDate,
Collections.singletonList(Type.SUPERVISOR)
);
return supervisorsFromIdeas(supervisorSubmittedFilter);
default:
return new HashSet<>();
}
}
private IdeaService.Filter setIdeaParams(Collection<Idea.Status> statuses, Set<ProjectType> pc, Date startDate, Date endDate, Collection<Type> types) {
private IdeaService.Filter setIdeaParams(
Collection<Idea.Status> statuses,
Set<ProjectType> pc,
Date startDate,
Date endDate,
Collection<Type> types
) {
final IdeaService.Filter ideaParams = new IdeaService.Filter();
if (statuses != null && !statuses.isEmpty()) {
ideaParams.setStatuses(statuses);

@ -1,8 +1,7 @@
package se.su.dsv.scipro.date;
import se.su.dsv.scipro.data.enums.DateStyle;
import java.util.Date;
import se.su.dsv.scipro.data.enums.DateStyle;
public interface DateService {
String format(Date date);

@ -1,14 +1,11 @@
package se.su.dsv.scipro.date;
import se.su.dsv.scipro.data.enums.DateStyle;
import java.text.SimpleDateFormat;
import java.util.Date;
import se.su.dsv.scipro.data.enums.DateStyle;
public class DateServiceImpl implements DateService {
private String findStyle(DateStyle style) {
return style.getFormat();
}

@ -1,10 +1,5 @@
package se.su.dsv.scipro.file;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
import jakarta.persistence.*;
import java.io.IOException;
import java.io.InputStream;
@ -13,6 +8,10 @@ import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
/**
* Metadata about a specific file. To get access to the underlying data you need a
@ -138,8 +137,7 @@ public class FileDescription extends DomainObject {
if (o == this) return true;
if (!(o instanceof FileDescription)) return false;
final FileDescription other = (FileDescription) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
return (other.canEqual(this) && Objects.equals(this.getId(), other.getId()));
}
@Override

@ -4,7 +4,6 @@ import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
@Transactional
public interface FileDescriptionRepo extends JpaRepository<FileDescription, Long>, QueryDslPredicateExecutor<FileDescription> {
}
public interface FileDescriptionRepo
extends JpaRepository<FileDescription, Long>, QueryDslPredicateExecutor<FileDescription> {}

@ -1,15 +1,14 @@
package se.su.dsv.scipro.file;
import se.su.dsv.scipro.system.GenericRepo;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.GenericRepo;
public class FileDescriptionRepoImpl extends GenericRepo<FileDescription, Long> implements FileDescriptionRepo {
@Inject
public FileDescriptionRepoImpl(Provider<EntityManager> em) {
super(em, FileDescription.class, QFileDescription.fileDescription);
}
}

@ -24,6 +24,7 @@ import java.util.Objects;
@Entity
@Table(name = "file_reference")
public class FileReference implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ -57,7 +58,7 @@ public class FileReference implements Serializable {
return false;
}
final FileReference that = (FileReference) o;
return Objects.equals(id, that.id) && fileDescription.equals(that.fileDescription);
return (Objects.equals(id, that.id) && fileDescription.equals(that.fileDescription));
}
@Override
@ -67,10 +68,7 @@ public class FileReference implements Serializable {
@Override
public String toString() {
return "FileReference{" +
"id=" + id +
", fileDescription=" + fileDescription +
'}';
return ("FileReference{" + "id=" + id + ", fileDescription=" + fileDescription + '}');
}
public String getName() {

@ -1,11 +1,10 @@
package se.su.dsv.scipro.file;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractRepository;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractRepository;
public class FileReferenceRepositoryImpl extends AbstractRepository implements FileReferenceRepository {

@ -1,8 +1,7 @@
package se.su.dsv.scipro.file;
import se.su.dsv.scipro.system.GenericService;
import java.io.InputStream;
import se.su.dsv.scipro.system.GenericService;
public interface FileService extends GenericService<FileDescription, Long> {
FileReference storeFile(FileUpload fileUpload);

@ -1,12 +1,11 @@
package se.su.dsv.scipro.file;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import java.io.InputStream;
import se.su.dsv.scipro.system.AbstractServiceImpl;
public class FileServiceImpl extends AbstractServiceImpl<FileDescription, Long> implements FileService {
@ -19,8 +18,8 @@ public class FileServiceImpl extends AbstractServiceImpl<FileDescription, Long>
Provider<EntityManager> em,
final FileReferenceRepository fileReferenceRepository,
final FileDescriptionRepo fileDescriptionRepository,
final FileStore fileStore)
{
final FileStore fileStore
) {
super(em, FileDescription.class, QFileDescription.fileDescription);
this.fileReferenceRepository = fileReferenceRepository;
this.fileDescriptionRepository = fileDescriptionRepository;
@ -80,5 +79,4 @@ public class FileServiceImpl extends AbstractServiceImpl<FileDescription, Long>
fileStore.deleteData(fileDescription);
}
}
}

@ -7,5 +7,5 @@ public enum FileSource {
PEER_REVIEW,
PEER_REQUEST,
FINAL_SEMINAR,
ACTIVITY_PLAN
ACTIVITY_PLAN,
}

@ -1,9 +1,8 @@
package se.su.dsv.scipro.file;
import se.su.dsv.scipro.system.User;
import java.io.InputStream;
import java.util.function.Function;
import se.su.dsv.scipro.system.User;
public interface FileUpload {
String getFileName();

@ -12,11 +12,10 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import java.util.Objects;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.DomainObject;
import java.util.Objects;
@Entity
@Table(name = "project_file")
public class ProjectFile extends DomainObject {
@ -88,12 +87,14 @@ public class ProjectFile extends DomainObject {
if (o == this) return true;
if (!(o instanceof ProjectFile)) return false;
final ProjectFile other = (ProjectFile) o;
return other.canEqual(this)
&& super.equals(o)
&& Objects.equals(this.getId(), other.getId())
&& Objects.equals(this.getProject(), other.getProject())
&& Objects.equals(this.getFileSource(), other.getFileSource())
&& Objects.equals(this.getFileDescription(), other.getFileDescription());
return (
other.canEqual(this) &&
super.equals(o) &&
Objects.equals(this.getId(), other.getId()) &&
Objects.equals(this.getProject(), other.getProject()) &&
Objects.equals(this.getFileSource(), other.getFileSource()) &&
Objects.equals(this.getFileDescription(), other.getFileDescription())
);
}
@Override
@ -103,7 +104,17 @@ public class ProjectFile extends DomainObject {
@Override
public String toString() {
return "ProjectFile(id=" + this.getId() + ", project=" + this.getProject() + ", fileSource=" + this.getFileSource() + ", fileDescription=" + this.getFileDescription() + ")";
return (
"ProjectFile(id=" +
this.getId() +
", project=" +
this.getProject() +
", fileSource=" +
this.getFileSource() +
", fileDescription=" +
this.getFileDescription() +
")"
);
}
// ----------------------------------------------------------------------------------

@ -1,13 +1,13 @@
package se.su.dsv.scipro.file;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.project.Project;
import java.util.*;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
public interface ProjectFileRepository extends JpaRepository<ProjectFile, Long>, QueryDslPredicateExecutor<ProjectFile> {
public interface ProjectFileRepository
extends JpaRepository<ProjectFile, Long>, QueryDslPredicateExecutor<ProjectFile> {
List<ProjectFile> latestUpload(Project project, int amount);
Collection<ProjectFile> getProjectFiles(Project project, Pageable pageable);

@ -2,16 +2,16 @@ package se.su.dsv.scipro.file;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQuery;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import java.util.*;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.Pageable;
public class ProjectFileRepositoryImpl extends AbstractServiceImpl<ProjectFile, Long> implements ProjectFileRepository {
@Inject
public ProjectFileRepositoryImpl(final Provider<EntityManager> em) {
super(em, ProjectFile.class, QProjectFile.projectFile);
@ -38,8 +38,13 @@ public class ProjectFileRepositoryImpl extends AbstractServiceImpl<ProjectFile,
@Override
public Optional<ProjectFile> findProjectFile(final FileDescription fileDescription, final Project project) {
return Optional.ofNullable(findOne(Expressions.allOf(
return Optional.ofNullable(
findOne(
Expressions.allOf(
QProjectFile.projectFile.fileReference.fileDescription.eq(fileDescription),
QProjectFile.projectFile.project.eq(project))));
QProjectFile.projectFile.project.eq(project)
)
)
);
}
}

@ -1,9 +1,8 @@
package se.su.dsv.scipro.file;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project;
import java.util.*;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.Pageable;
public interface ProjectFileService {
ProjectFile store(ProjectFileUpload projectFileUpload, final FileSource fileSource);

@ -1,26 +1,22 @@
package se.su.dsv.scipro.file;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import java.util.*;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.Pageable;
public class ProjectFileServiceImpl implements ProjectFileService {
private final FileService fileService;
private final ProjectFileRepository projectFileRepository;
@Inject
public ProjectFileServiceImpl(
final FileService fileService,
final ProjectFileRepository projectFileRepository)
{
public ProjectFileServiceImpl(final FileService fileService, final ProjectFileRepository projectFileRepository) {
this.fileService = fileService;
this.projectFileRepository = projectFileRepository;
}
@Override
@Transactional
public ProjectFile store(final ProjectFileUpload projectFileUpload, final FileSource fileSource) {
@ -30,7 +26,11 @@ public class ProjectFileServiceImpl implements ProjectFileService {
@Override
@Transactional
public ProjectFile promote(final FileDescription fileDescription, final Project project, final FileSource fileSource) {
public ProjectFile promote(
final FileDescription fileDescription,
final Project project,
final FileSource fileSource
) {
Optional<ProjectFile> existing = projectFileRepository.findProjectFile(fileDescription, project);
if (existing.isPresent()) {
return existing.get();

@ -1,6 +1,5 @@
package se.su.dsv.scipro.file;
import se.su.dsv.scipro.project.Project;
public interface ProjectFileUpload extends FileUpload {

@ -4,6 +4,7 @@ import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.User;
class AbstractOppositionEvent {
private final FinalSeminarOpposition opposition;
protected AbstractOppositionEvent(FinalSeminarOpposition opposition) {

@ -4,6 +4,7 @@ import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.User;
class AbstractParticipationEvent {
private final FinalSeminarActiveParticipation participation;
protected AbstractParticipationEvent(FinalSeminarActiveParticipation participation) {

@ -4,6 +4,7 @@ import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.User;
class AbstractRespondentEvent {
private final FinalSeminarRespondent respondent;
protected AbstractRespondentEvent(FinalSeminarRespondent respondent) {

@ -3,74 +3,84 @@ package se.su.dsv.scipro.finalseminar;
import java.util.function.Function;
public abstract class ActiveParticipationRegistrationErrorStatus {
ActiveParticipationRegistrationErrorStatus() {
}
ActiveParticipationRegistrationErrorStatus() {}
public abstract <A> A fold(
Function<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
Function<ParticipationFinalSeminarCancelled, A> g);
Function<ParticipationFinalSeminarCancelled, A> g
);
}
final class TooManyParticipants extends ActiveParticipationRegistrationErrorStatus {
@Override
public <A> A fold(
Function<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
Function<ParticipationFinalSeminarCancelled, A> g) {
Function<ParticipationFinalSeminarCancelled, A> g
) {
return a.apply(this);
}
}
final class ManualParticipants extends ActiveParticipationRegistrationErrorStatus {
@Override
public <A> A fold(
Function<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
Function<ParticipationFinalSeminarCancelled, A> g) {
Function<ParticipationFinalSeminarCancelled, A> g
) {
return b.apply(this);
}
}
final class ParticipationAlreadyParticipating extends ActiveParticipationRegistrationErrorStatus {
@Override
public <A> A fold(
Function<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
Function<ParticipationFinalSeminarCancelled, A> g) {
Function<ParticipationFinalSeminarCancelled, A> g
) {
return e.apply(this);
}
}
final class ParticipationAlreadyHappened extends ActiveParticipationRegistrationErrorStatus {
@Override
public <A> A fold(
Function<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
Function<ParticipationFinalSeminarCancelled, A> g) {
Function<ParticipationFinalSeminarCancelled, A> g
) {
return f.apply(this);
}
}
final class ParticipationFinalSeminarCancelled extends ActiveParticipationRegistrationErrorStatus {
@Override
public <A> A fold(
Function<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
Function<ParticipationFinalSeminarCancelled, A> g) {
Function<ParticipationFinalSeminarCancelled, A> g
) {
return g.apply(this);
}
}

@ -1,13 +1,12 @@
package se.su.dsv.scipro.finalseminar;
import java.util.List;
import java.util.Optional;
import se.su.dsv.scipro.project.Author;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
import java.util.List;
import java.util.Optional;
public interface AuthorRepository {
Optional<Author> findByProjectAndUser(Project project, User user);

@ -1,5 +1,10 @@
package se.su.dsv.scipro.finalseminar;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import java.util.List;
import java.util.Optional;
import se.su.dsv.scipro.project.Author;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.project.ProjectStatus;
@ -8,13 +13,8 @@ import se.su.dsv.scipro.system.AbstractRepository;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import java.util.List;
import java.util.Optional;
public class AuthorRepositoryImpl extends AbstractRepository implements AuthorRepository {
@Inject
public AuthorRepositoryImpl(Provider<EntityManager> em) {
super(em);
@ -23,11 +23,7 @@ public class AuthorRepositoryImpl extends AbstractRepository implements AuthorRe
@Override
public Optional<Author> findByProjectAndUser(Project project, User user) {
final QAuthor author = QAuthor.author;
final Author author1 = from(author)
.where(
author.project.eq(project),
author.user.eq(user))
.fetchOne();
final Author author1 = from(author).where(author.project.eq(project), author.user.eq(user)).fetchOne();
return Optional.ofNullable(author1);
}
@ -35,9 +31,11 @@ public class AuthorRepositoryImpl extends AbstractRepository implements AuthorRe
public List<Author> getSubscribersWithActiveProjectOnType(ProjectType projectType) {
final QAuthor author = QAuthor.author;
return from(author)
.where(author.subscribedToFinalSeminarNotifications.isTrue(),
.where(
author.subscribedToFinalSeminarNotifications.isTrue(),
author.project.projectType.eq(projectType),
author.project.projectStatus.eq(ProjectStatus.ACTIVE))
author.project.projectStatus.eq(ProjectStatus.ACTIVE)
)
.fetch();
}
}

@ -1,15 +1,6 @@
package se.su.dsv.scipro.finalseminar;
import com.querydsl.core.annotations.QueryInit;
import jakarta.persistence.GenerationType;
import se.su.dsv.scipro.data.dataobjects.Member;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.Language;
import se.su.dsv.scipro.system.LazyDeletableDomainObject;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
import jakarta.persistence.Basic;
import jakarta.persistence.Cacheable;
import jakarta.persistence.CascadeType;
@ -18,12 +9,12 @@ import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -32,11 +23,19 @@ import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import se.su.dsv.scipro.data.dataobjects.Member;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.Language;
import se.su.dsv.scipro.system.LazyDeletableDomainObject;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
@Entity
@Table(name = "final_seminar")
@Cacheable(true)
public class FinalSeminar extends LazyDeletableDomainObject {
public static final String U_SINGULAR = "Final seminar";
public static final int DEFAULT_MAX_OPPONENTS = 2;
@ -118,8 +117,7 @@ public class FinalSeminar extends LazyDeletableDomainObject {
// ----------------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------------
public FinalSeminar() {
}
public FinalSeminar() {}
public FinalSeminar(int maxOpponents, int maxParticipants) {
this.maxOpponents = maxOpponents;
@ -273,9 +271,7 @@ public class FinalSeminar extends LazyDeletableDomainObject {
if (o == this) return true;
if (!(o instanceof FinalSeminar)) return false;
final FinalSeminar other = (FinalSeminar) o;
return other.canEqual(this)
&& super.equals(o)
&& Objects.equals(this.getId(), other.getId());
return (other.canEqual(this) && super.equals(o) && Objects.equals(this.getId(), other.getId()));
}
@Override
@ -285,14 +281,35 @@ public class FinalSeminar extends LazyDeletableDomainObject {
@Override
public String toString() {
return "FinalSeminar(id=" + this.getId() + ", project=" + this.getProject() + ", startDate=" +
this.getStartDate() + ", room=" + this.getRoom() + ", activeParticipations=" +
this.getActiveParticipations() + ", oppositions=" + this.getOppositions() +
", respondents=" + this.getRespondents() + ", document=" + this.getDocument() +
", documentUploadDate=" + this.getDocumentUploadDate() + ", presentationLanguage=" +
this.getPresentationLanguage() + ", maxOpponents=" + this.getMaxOpponents() +
", maxParticipants=" + this.getMaxParticipants() + ", creationReason=" +
this.getCreationReason() + ")";
return (
"FinalSeminar(id=" +
this.getId() +
", project=" +
this.getProject() +
", startDate=" +
this.getStartDate() +
", room=" +
this.getRoom() +
", activeParticipations=" +
this.getActiveParticipations() +
", oppositions=" +
this.getOppositions() +
", respondents=" +
this.getRespondents() +
", document=" +
this.getDocument() +
", documentUploadDate=" +
this.getDocumentUploadDate() +
", presentationLanguage=" +
this.getPresentationLanguage() +
", maxOpponents=" +
this.getMaxOpponents() +
", maxParticipants=" +
this.getMaxParticipants() +
", creationReason=" +
this.getCreationReason() +
")"
);
}
// ----------------------------------------------------------------------------------

@ -1,18 +1,18 @@
package se.su.dsv.scipro.finalseminar;
import jakarta.persistence.JoinColumn;
import se.su.dsv.scipro.project.Project;
import jakarta.persistence.Cacheable;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.util.Objects;
import se.su.dsv.scipro.project.Project;
@Entity
@Table(name = "final_seminar_active_participation")
@Cacheable(true)
public class FinalSeminarActiveParticipation extends FinalSeminarParticipation {
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (final_seminar_active_participation)
// referencing other tables.
@ -40,9 +40,7 @@ public class FinalSeminarActiveParticipation extends FinalSeminarParticipation {
if (o == this) return true;
if (!(o instanceof FinalSeminarActiveParticipation)) return false;
final FinalSeminarActiveParticipation other = (FinalSeminarActiveParticipation) o;
return other.canEqual(this)
&& super.equals(o)
&& Objects.equals(this.project, other.project);
return (other.canEqual(this) && super.equals(o) && Objects.equals(this.project, other.project));
}
@Override

@ -1,10 +1,9 @@
package se.su.dsv.scipro.finalseminar;
import java.util.*;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
import java.util.*;
public interface FinalSeminarActiveParticipationRepository {
List<FinalSeminarActiveParticipation> findByParticipatingUserAndLevel(User user, ProjectType projectType);
}

@ -1,15 +1,17 @@
package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.system.AbstractRepository;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import java.util.*;
import se.su.dsv.scipro.system.AbstractRepository;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
public class FinalSeminarActiveParticipationRepositoryImpl
extends AbstractRepository
implements FinalSeminarActiveParticipationRepository {
public class FinalSeminarActiveParticipationRepositoryImpl extends AbstractRepository implements FinalSeminarActiveParticipationRepository {
@Inject
public FinalSeminarActiveParticipationRepositoryImpl(Provider<EntityManager> em) {
super(em);

@ -4,6 +4,5 @@ import se.su.dsv.scipro.system.GenericService;
import se.su.dsv.scipro.system.User;
public interface FinalSeminarActiveParticipationService extends GenericService<FinalSeminarActiveParticipation, Long> {
FinalSeminarActiveParticipation findByFinalSeminarUser(FinalSeminar finalSeminar, User user);
}

@ -1,22 +1,26 @@
package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.User;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.User;
public class FinalSeminarActiveParticipationServiceImpl extends AbstractServiceImpl<FinalSeminarActiveParticipation, Long> implements FinalSeminarActiveParticipationService {
public class FinalSeminarActiveParticipationServiceImpl
extends AbstractServiceImpl<FinalSeminarActiveParticipation, Long>
implements FinalSeminarActiveParticipationService {
@Inject
public FinalSeminarActiveParticipationServiceImpl(Provider<EntityManager> em) {
super(em, FinalSeminarActiveParticipation.class, QFinalSeminarActiveParticipation.finalSeminarActiveParticipation);
super(
em,
FinalSeminarActiveParticipation.class,
QFinalSeminarActiveParticipation.finalSeminarActiveParticipation
);
}
@Override
public FinalSeminarActiveParticipation findByFinalSeminarUser(FinalSeminar finalSeminar, User user) {
for (FinalSeminarActiveParticipation fsap : finalSeminar.getActiveParticipations()) {
if (fsap.getUser().equals(user)) {
return fsap;
@ -24,5 +28,4 @@ public class FinalSeminarActiveParticipationServiceImpl extends AbstractServiceI
}
return null;
}
}

@ -3,6 +3,7 @@ package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.project.Project;
public final class FinalSeminarCreatedEvent {
private final FinalSeminar finalSeminar;
public FinalSeminar getFinalSeminar() {

@ -2,6 +2,10 @@ package se.su.dsv.scipro.finalseminar;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import jakarta.inject.Inject;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import se.su.dsv.scipro.data.dataobjects.Member;
import se.su.dsv.scipro.notifications.NotificationController;
import se.su.dsv.scipro.notifications.dataobject.NotificationSource;
@ -9,12 +13,8 @@ import se.su.dsv.scipro.notifications.dataobject.SeminarEvent;
import se.su.dsv.scipro.project.Author;
import se.su.dsv.scipro.system.User;
import jakarta.inject.Inject;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class FinalSeminarCreationSubscribers {
private final AuthorRepository authorRepository;
private final FinalSeminarService finalSeminarService;
private final NotificationController notificationController;
@ -22,8 +22,8 @@ public class FinalSeminarCreationSubscribers {
FinalSeminarCreationSubscribers(
AuthorRepository authorRepository,
FinalSeminarService finalSeminarService,
NotificationController notificationController)
{
NotificationController notificationController
) {
this.authorRepository = authorRepository;
this.finalSeminarService = finalSeminarService;
this.notificationController = notificationController;
@ -34,20 +34,27 @@ public class FinalSeminarCreationSubscribers {
AuthorRepository authorRepository,
FinalSeminarService finalSeminarService,
NotificationController notificationController,
EventBus eventBus)
{
EventBus eventBus
) {
this(authorRepository, finalSeminarService, notificationController);
eventBus.register(this);
}
@Subscribe
public void finalSeminarCreated(FinalSeminarCreatedEvent event) {
List<Author> subscribers = authorRepository.getSubscribersWithActiveProjectOnType(event.getFinalSeminar().getProjectType());
List<Author> subscribers = authorRepository.getSubscribersWithActiveProjectOnType(
event.getFinalSeminar().getProjectType()
);
Set<Member> users = getSubscribersStillNeedingOppositionOrParticipation(subscribers)
.stream()
.map(user -> new Member(user, Member.Type.OPPONENT))
.collect(Collectors.toSet());
notificationController.notifyCustomSeminar(event.getFinalSeminar(), SeminarEvent.Event.CREATED, new NotificationSource(), users);
notificationController.notifyCustomSeminar(
event.getFinalSeminar(),
SeminarEvent.Event.CREATED,
new NotificationSource(),
users
);
}
private List<User> getSubscribersStillNeedingOppositionOrParticipation(List<Author> subscribers) {
@ -59,13 +66,18 @@ public class FinalSeminarCreationSubscribers {
}
private boolean onlyFailedParticipations(Author subscriber) {
return finalSeminarService.findUserParticipating(subscriber.getProject(), subscriber.getUser())
return finalSeminarService
.findUserParticipating(subscriber.getProject(), subscriber.getUser())
.stream()
.noneMatch(FinalSeminarParticipation::isApproved);
}
private boolean onlyFailedOppositions(Author subscriber) {
return finalSeminarService.findFinalSeminarOppositionsByOpponentAndProjectType(subscriber.getProject().getProjectType(), subscriber.getUser())
return finalSeminarService
.findFinalSeminarOppositionsByOpponentAndProjectType(
subscriber.getProject().getProjectType(),
subscriber.getUser()
)
.stream()
.noneMatch(FinalSeminarParticipation::isApproved);
}

@ -3,6 +3,7 @@ package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.project.Project;
public final class FinalSeminarDeletedEvent {
private final FinalSeminar finalSeminar;
public FinalSeminar getFinalSeminar() {

@ -9,6 +9,5 @@ public record FinalSeminarDetails(
int maxOpponents,
Language presentationLanguage,
Language reportLanguage,
String extraInfo)
{
}
String extraInfo
) {}

@ -1,17 +1,16 @@
package se.su.dsv.scipro.finalseminar;
public enum FinalSeminarGrade {
APPROVED {
@Override
public String toString() {
return "approved";
}
}, NOT_APPROVED {
},
NOT_APPROVED {
@Override
public String toString() {
return "not approved";
}
}
},
}

@ -2,5 +2,4 @@ package se.su.dsv.scipro.finalseminar;
import java.time.LocalDateTime;
public record FinalSeminarMovedEvent(FinalSeminar finalSeminar, LocalDateTime from, LocalDateTime to) {
}
public record FinalSeminarMovedEvent(FinalSeminar finalSeminar, LocalDateTime from, LocalDateTime to) {}

@ -1,10 +1,5 @@
package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.report.OppositionReport;
import se.su.dsv.scipro.system.ProjectType;
import jakarta.persistence.Basic;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
@ -13,12 +8,16 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import java.util.Objects;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.report.OppositionReport;
import se.su.dsv.scipro.system.ProjectType;
@Entity
@Table(name = "final_seminar_opposition")
public class FinalSeminarOpposition extends FinalSeminarParticipation {
private static final int FEEDBACK_LENGTH = 2000;
// ----------------------------------------------------------------------------------
@ -47,8 +46,7 @@ public class FinalSeminarOpposition extends FinalSeminarParticipation {
// ----------------------------------------------------------------------------------
// JPA-mappings of other tables referencing to this table (final_seminar_opposition)
// ----------------------------------------------------------------------------------
@OneToOne(optional = true, orphanRemoval = true, cascade = CascadeType.ALL,
mappedBy = "finalSeminarOpposition")
@OneToOne(optional = true, orphanRemoval = true, cascade = CascadeType.ALL, mappedBy = "finalSeminarOpposition")
private OppositionReport oppositionReport;
// ----------------------------------------------------------------------------------
@ -102,9 +100,7 @@ public class FinalSeminarOpposition extends FinalSeminarParticipation {
if (o == this) return true;
if (!(o instanceof FinalSeminarOpposition)) return false;
final FinalSeminarOpposition other = (FinalSeminarOpposition) o;
return other.canEqual(this)
&& super.equals(o)
&& Objects.equals(this.getProject(), other.getProject());
return (other.canEqual(this) && super.equals(o) && Objects.equals(this.getProject(), other.getProject()));
}
@Override

@ -1,15 +1,14 @@
package se.su.dsv.scipro.finalseminar;
import jakarta.transaction.Transactional;
import java.util.*;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.system.User;
import java.util.*;
@Transactional
public interface FinalSeminarOppositionRepo extends JpaRepository<FinalSeminarOpposition, Long>, QueryDslPredicateExecutor<FinalSeminarOpposition> {
public interface FinalSeminarOppositionRepo
extends JpaRepository<FinalSeminarOpposition, Long>, QueryDslPredicateExecutor<FinalSeminarOpposition> {
List<FinalSeminarOpposition> findByOpposingUserAndType(User user, ProjectType projectType);
}

@ -1,15 +1,17 @@
package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.system.GenericRepo;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import java.util.*;
import se.su.dsv.scipro.system.GenericRepo;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
public class FinalSeminarOppositionRepoImpl
extends GenericRepo<FinalSeminarOpposition, Long>
implements FinalSeminarOppositionRepo {
public class FinalSeminarOppositionRepoImpl extends GenericRepo<FinalSeminarOpposition,Long> implements FinalSeminarOppositionRepo {
@Inject
public FinalSeminarOppositionRepoImpl(Provider<EntityManager> em) {
super(em, FinalSeminarOpposition.class, QFinalSeminarOpposition.finalSeminarOpposition);

@ -3,8 +3,6 @@ package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.system.GenericService;
public interface FinalSeminarOppositionService extends GenericService<FinalSeminarOpposition, Long> {
@Override
void delete(Long aLong);
}

@ -1,12 +1,14 @@
package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.AbstractServiceImpl;
public class FinalSeminarOppositionServiceImpl
extends AbstractServiceImpl<FinalSeminarOpposition, Long>
implements FinalSeminarOppositionService {
public class FinalSeminarOppositionServiceImpl extends AbstractServiceImpl<FinalSeminarOpposition, Long> implements FinalSeminarOppositionService {
@Inject
public FinalSeminarOppositionServiceImpl(Provider<EntityManager> em) {
super(em, FinalSeminarOpposition.class, QFinalSeminarOpposition.finalSeminarOpposition);

@ -10,13 +10,13 @@ import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MappedSuperclass;
import java.util.Objects;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
import java.util.Objects;
@MappedSuperclass
public abstract class FinalSeminarParticipation extends DomainObject {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@ -45,8 +45,7 @@ public abstract class FinalSeminarParticipation extends DomainObject {
// ----------------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------------
protected FinalSeminarParticipation() {
}
protected FinalSeminarParticipation() {}
protected FinalSeminarParticipation(User user, FinalSeminar finalSeminar) {
this.user = user;
@ -97,9 +96,11 @@ public abstract class FinalSeminarParticipation extends DomainObject {
if (o == this) return true;
if (!(o instanceof FinalSeminarParticipation)) return false;
final FinalSeminarParticipation other = (FinalSeminarParticipation) o;
return other.canEqual(this)
&& Objects.equals(this.getUser(), other.getUser())
&& Objects.equals(this.getFinalSeminar(), other.getFinalSeminar());
return (
other.canEqual(this) &&
Objects.equals(this.getUser(), other.getUser()) &&
Objects.equals(this.getFinalSeminar(), other.getFinalSeminar())
);
}
@Override

@ -1,13 +1,13 @@
package se.su.dsv.scipro.finalseminar;
import jakarta.transaction.Transactional;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.AbstractRepository;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractRepository;
public class FinalSeminarRepositoryImpl extends AbstractRepository implements FinalSeminarRepository {
@Inject
public FinalSeminarRepositoryImpl(Provider<EntityManager> em) {
super(em);
@ -19,8 +19,7 @@ public class FinalSeminarRepositoryImpl extends AbstractRepository implements Fi
EntityManager entityManager = em();
if (entityManager.contains(finalSeminar)) {
return entityManager.merge(finalSeminar);
}
else {
} else {
entityManager.persist(finalSeminar);
return finalSeminar;
}

@ -1,19 +1,17 @@
package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.User;
import jakarta.persistence.Cacheable;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.User;
@Entity
@Table(name = "final_seminar_respondent")
@Cacheable(true)
public class FinalSeminarRespondent extends FinalSeminarParticipation {
protected FinalSeminarRespondent() {
}
protected FinalSeminarRespondent() {}
public FinalSeminarRespondent(User student, FinalSeminar finalSeminar) {
super(student, finalSeminar);

@ -1,8 +1,7 @@
package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.system.GenericService;
import java.util.List;
import se.su.dsv.scipro.system.GenericService;
public interface FinalSeminarRespondentService extends GenericService<FinalSeminarRespondent, Long> {
List<FinalSeminarRespondent> findOrCreate(FinalSeminar finalSeminar);

@ -1,21 +1,22 @@
package se.su.dsv.scipro.finalseminar;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.User;
import static com.querydsl.core.types.dsl.Expressions.allOf;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import static com.querydsl.core.types.dsl.Expressions.allOf;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.User;
@Named
public class FinalSeminarRespondentServiceImpl extends AbstractServiceImpl<FinalSeminarRespondent, Long> implements FinalSeminarRespondentService {
public class FinalSeminarRespondentServiceImpl
extends AbstractServiceImpl<FinalSeminarRespondent, Long>
implements FinalSeminarRespondentService {
@Inject
public FinalSeminarRespondentServiceImpl(Provider<EntityManager> em) {
@ -23,9 +24,12 @@ public class FinalSeminarRespondentServiceImpl extends AbstractServiceImpl<Final
}
private FinalSeminarRespondent findOrCreate(User student, FinalSeminar finalSeminar) {
FinalSeminarRespondent finalSeminarRespondent = findOne(allOf(
FinalSeminarRespondent finalSeminarRespondent = findOne(
allOf(
QFinalSeminarRespondent.finalSeminarRespondent.user.eq(student),
QFinalSeminarRespondent.finalSeminarRespondent.finalSeminar.eq(finalSeminar)));
QFinalSeminarRespondent.finalSeminarRespondent.finalSeminar.eq(finalSeminar)
)
);
if (finalSeminarRespondent == null) {
finalSeminarRespondent = new FinalSeminarRespondent(student, finalSeminar);
return save(finalSeminarRespondent);

@ -1,10 +1,9 @@
package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.util.Either;
import java.time.LocalDate;
import java.time.LocalDateTime;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.util.Either;
public interface FinalSeminarScheduling {
Either<SchedulingError, FinalSeminar> schedule(Project project, LocalDateTime when, FinalSeminarDetails details);

@ -1,28 +1,49 @@
package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.*;
import se.su.dsv.scipro.util.Either;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.*;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.util.Either;
public interface FinalSeminarService extends GenericService<FinalSeminar, Long>, FilteredService<FinalSeminar, Long, FinalSeminarService.Filter>, FinalSeminarScheduling {
Either<OppositionRegistrationErrorStatus, FinalSeminarOpposition> attemptAddOpposition(User student, FinalSeminar finalSeminar, Project project);
public interface FinalSeminarService
extends
GenericService<FinalSeminar, Long>,
FilteredService<FinalSeminar, Long, FinalSeminarService.Filter>,
FinalSeminarScheduling {
Either<OppositionRegistrationErrorStatus, FinalSeminarOpposition> attemptAddOpposition(
User student,
FinalSeminar finalSeminar,
Project project
);
Either<ActiveParticipationRegistrationErrorStatus, FinalSeminarActiveParticipation> attemptAddActiveParticipation(User student, FinalSeminar finalSeminar, Project project);
Either<ActiveParticipationRegistrationErrorStatus, FinalSeminarActiveParticipation> attemptAddActiveParticipation(
User student,
FinalSeminar finalSeminar,
Project project
);
Either<OpposeError, FinalSeminarOpposition> attemptAddOppositionAsSupervisor(User student, FinalSeminar finalSeminar, Project project);
Either<OpposeError, FinalSeminarOpposition> attemptAddOppositionAsSupervisor(
User student,
FinalSeminar finalSeminar,
Project project
);
Either<ParticipateError, FinalSeminarActiveParticipation> attemptAddActiveParticipationAsSupervisor(User student, FinalSeminar finalSeminar, Project project);
Either<ParticipateError, FinalSeminarActiveParticipation> attemptAddActiveParticipationAsSupervisor(
User student,
FinalSeminar finalSeminar,
Project project
);
Either<OppositionRegistrationErrorStatus, Void> canOppose(User Student, FinalSeminar finalSeminar, Project project);
Either<ActiveParticipationRegistrationErrorStatus, Void> canActiveParticipate(User student, FinalSeminar finalSeminar);
Either<ActiveParticipationRegistrationErrorStatus, Void> canActiveParticipate(
User student,
FinalSeminar finalSeminar
);
Iterable<FinalSeminar> findAll(Filter params);
@ -51,7 +72,10 @@ public interface FinalSeminarService extends GenericService<FinalSeminar, Long>,
FinalSeminar cancel(FinalSeminar finalSeminar);
List<FinalSeminarOpposition> findFinalSeminarOppositionsByOpponentAndProjectType(ProjectType projectType, User user);
List<FinalSeminarOpposition> findFinalSeminarOppositionsByOpponentAndProjectType(
ProjectType projectType,
User user
);
List<FinalSeminarActiveParticipation> findUserParticipating(Project project, User user);
@ -60,6 +84,7 @@ public interface FinalSeminarService extends GenericService<FinalSeminar, Long>,
void toggleSubscriptionToSeminarCreationNotifications(Project project, User user);
class Filter implements Serializable {
private Date fromDate;
private Date toDate;
private Boolean lazyDeleted;
@ -147,16 +172,18 @@ public interface FinalSeminarService extends GenericService<FinalSeminar, Long>,
if (o == this) return true;
if (!(o instanceof Filter)) return false;
final Filter other = (Filter) o;
return other.canEqual(this)
&& Objects.equals(this.getFromDate(), other.getFromDate())
&& Objects.equals(this.getToDate(), other.getToDate())
&& Objects.equals(this.getLazyDeleted(), other.getLazyDeleted())
&& Objects.equals(this.getExempted(), other.getExempted())
&& Objects.equals(this.getOnlyActiveProjects(), other.getOnlyActiveProjects())
&& Objects.equals(this.getOnlyActiveOrCompletedProjects(), other.getOnlyActiveOrCompletedProjects())
&& Objects.equals(this.getHeadSupervisor(), other.getHeadSupervisor())
&& Objects.equals(this.getDegreeType(), other.getDegreeType())
&& Objects.equals(this.onlyNonManualParticipants, other.onlyNonManualParticipants);
return (
other.canEqual(this) &&
Objects.equals(this.getFromDate(), other.getFromDate()) &&
Objects.equals(this.getToDate(), other.getToDate()) &&
Objects.equals(this.getLazyDeleted(), other.getLazyDeleted()) &&
Objects.equals(this.getExempted(), other.getExempted()) &&
Objects.equals(this.getOnlyActiveProjects(), other.getOnlyActiveProjects()) &&
Objects.equals(this.getOnlyActiveOrCompletedProjects(), other.getOnlyActiveOrCompletedProjects()) &&
Objects.equals(this.getHeadSupervisor(), other.getHeadSupervisor()) &&
Objects.equals(this.getDegreeType(), other.getDegreeType()) &&
Objects.equals(this.onlyNonManualParticipants, other.onlyNonManualParticipants)
);
}
protected boolean canEqual(final Object other) {
@ -174,21 +201,34 @@ public interface FinalSeminarService extends GenericService<FinalSeminar, Long>,
this.getOnlyActiveOrCompletedProjects(),
this.getHeadSupervisor(),
this.getDegreeType(),
this.getOnlyNonManualParticipants());
this.getOnlyNonManualParticipants()
);
}
@Override
public String toString() {
return "FinalSeminarService.Filter(" +
"fromDate=" + this.getFromDate()
+ ", toDate=" + this.getToDate()
+ ", lazyDeleted=" + this.getLazyDeleted()
+ ", exempted=" + this.getExempted()
+ ", onlyActiveProjects=" + this.getOnlyActiveProjects()
+ ", onlyActiveOrCompletedProjects=" + this.getOnlyActiveOrCompletedProjects()
+ ", headSupervisor=" + this.getHeadSupervisor()
+ ", degreeType=" + this.getDegreeType()
+ ", onlyNonManualParticipants=" + this.getOnlyNonManualParticipants() + ")";
return (
"FinalSeminarService.Filter(" +
"fromDate=" +
this.getFromDate() +
", toDate=" +
this.getToDate() +
", lazyDeleted=" +
this.getLazyDeleted() +
", exempted=" +
this.getExempted() +
", onlyActiveProjects=" +
this.getOnlyActiveProjects() +
", onlyActiveOrCompletedProjects=" +
this.getOnlyActiveOrCompletedProjects() +
", headSupervisor=" +
this.getHeadSupervisor() +
", degreeType=" +
this.getDegreeType() +
", onlyNonManualParticipants=" +
this.getOnlyNonManualParticipants() +
")"
);
}
}
}

@ -1,11 +1,16 @@
package se.su.dsv.scipro.finalseminar;
import com.google.common.eventbus.EventBus;
import jakarta.transaction.Transactional;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.BooleanExpression;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.Pageable;
import jakarta.transaction.Transactional;
import java.time.*;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.file.FileService;
import se.su.dsv.scipro.misc.DaysService;
@ -17,25 +22,22 @@ import se.su.dsv.scipro.report.OppositionReportService;
import se.su.dsv.scipro.reviewing.RoughDraftApproval;
import se.su.dsv.scipro.reviewing.RoughDraftApprovalService;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
import se.su.dsv.scipro.util.Either;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.time.*;
import java.util.Date;
import java.util.List;
import java.util.Optional;
public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, Long> implements FinalSeminarService {
@Inject
FinalSeminarSettingsService finalSeminarSettingsService;
@Inject
DaysService daysService;
@Inject
OppositionReportService oppositionReportService;
@Inject
NonWorkDayPeriodService nonWorkDayPeriodService;
@ -58,7 +60,8 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
FinalSeminarActiveParticipationRepository finalSeminarActiveParticipationRepository,
FinalSeminarRepository finalSeminarRepository,
Clock clock,
RoughDraftApprovalService roughDraftApprovalService) {
RoughDraftApprovalService roughDraftApprovalService
) {
super(em, FinalSeminar.class, QFinalSeminar.finalSeminar);
this.eventBus = eventBus;
this.authorRepository = authorRepository;
@ -72,7 +75,11 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
@Override
@Transactional
public Either<SchedulingError, FinalSeminar> schedule(Project project, LocalDateTime when, FinalSeminarDetails details) {
public Either<SchedulingError, FinalSeminar> schedule(
Project project,
LocalDateTime when,
FinalSeminarDetails details
) {
if (project.isFinalSeminarRuleExempted()) {
return createSeminar(project, when, details);
}
@ -80,7 +87,8 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
SchedulingError violation = validateSchedulingRules(when.toLocalDate());
if (violation != null) return Either.left(violation);
boolean roughDraftApproved = roughDraftApprovalService.findBy(project)
boolean roughDraftApproved = roughDraftApprovalService
.findBy(project)
.map(RoughDraftApproval::isApproved)
.orElse(Boolean.FALSE);
if (!roughDraftApproved) {
@ -90,8 +98,7 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
final FinalSeminar current = findByProject(project);
if (current == null) {
return createSeminar(project, when, details);
}
else {
} else {
// Assume double click sends the same data so no need to change anything
return Either.right(current);
}
@ -118,7 +125,8 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
private Either<SchedulingError, FinalSeminar> createSeminar(
Project project,
LocalDateTime when,
FinalSeminarDetails details) {
FinalSeminarDetails details
) {
FinalSeminar finalSeminar = new FinalSeminar(project);
FinalSeminar persisted = setDetails(finalSeminar, when, details);
eventBus.post(new FinalSeminarCreatedEvent(persisted));
@ -211,7 +219,11 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
}
@Override
public Either<OppositionRegistrationErrorStatus, Void> canOppose(User Student, FinalSeminar finalSeminar, Project project) {
public Either<OppositionRegistrationErrorStatus, Void> canOppose(
User Student,
FinalSeminar finalSeminar,
Project project
) {
if (finalSeminar.isCancelled()) {
return Either.left(new FinalSeminarCancelled());
}
@ -227,7 +239,11 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
if (finalSeminar.getOppositions().size() >= finalSeminar.getMaxOpponents()) {
return Either.left(new TooManyOpponents());
}
for (FinalSeminarOpposition opposition : finalSeminarOppositionRepository.findByOpposingUserAndType(Student, project.getProjectType())) {
List<FinalSeminarOpposition> oppositions = finalSeminarOppositionRepository.findByOpposingUserAndType(
Student,
project.getProjectType()
);
for (FinalSeminarOpposition opposition : oppositions) {
if (opposition.getGrade() == null) {
return Either.left(new UngradedOpposition());
} else if (opposition.getGrade() == FinalSeminarGrade.APPROVED) {
@ -244,7 +260,10 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
}
@Override
public Either<ActiveParticipationRegistrationErrorStatus, Void> canActiveParticipate(User student, FinalSeminar finalSeminar) {
public Either<ActiveParticipationRegistrationErrorStatus, Void> canActiveParticipate(
User student,
FinalSeminar finalSeminar
) {
if (finalSeminar.getManualParticipants()) {
return Either.left(new ManualParticipants());
}
@ -264,20 +283,32 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
}
private boolean alreadyParticipatingInSeminar(User user, FinalSeminar finalSeminar) {
return alreadyOpponent(user, finalSeminar) || isAuthor(user, finalSeminar) || alreadyActiveParticipant(user, finalSeminar);
return (
alreadyOpponent(user, finalSeminar) ||
isAuthor(user, finalSeminar) ||
alreadyActiveParticipant(user, finalSeminar)
);
}
@Override
@Transactional
public Either<OppositionRegistrationErrorStatus, FinalSeminarOpposition> attemptAddOpposition(final User student, final FinalSeminar finalSeminar, final Project project) {
return canOppose(student, finalSeminar, project)
.map(allowed -> createAndSaveOpposition(student, finalSeminar, project));
public Either<OppositionRegistrationErrorStatus, FinalSeminarOpposition> attemptAddOpposition(
final User student,
final FinalSeminar finalSeminar,
final Project project
) {
return canOppose(student, finalSeminar, project).map(allowed ->
createAndSaveOpposition(student, finalSeminar, project)
);
}
@Override
@Transactional
public Either<OpposeError, FinalSeminarOpposition> attemptAddOppositionAsSupervisor(User student, FinalSeminar finalSeminar, Project project) {
public Either<OpposeError, FinalSeminarOpposition> attemptAddOppositionAsSupervisor(
User student,
FinalSeminar finalSeminar,
Project project
) {
if (alreadyActiveParticipant(student, finalSeminar)) {
return Either.left(OpposeError.ALREADY_PARTICIPANT);
} else if (alreadyOpponent(student, finalSeminar)) {
@ -301,14 +332,22 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
@Override
@Transactional
public Either<ActiveParticipationRegistrationErrorStatus, FinalSeminarActiveParticipation> attemptAddActiveParticipation(final User student, final FinalSeminar finalSeminar, final Project project) {
return canActiveParticipate(student, finalSeminar)
.map(allowed -> createAndSaveActiveParticipation(student, finalSeminar, project));
public Either<
ActiveParticipationRegistrationErrorStatus,
FinalSeminarActiveParticipation
> attemptAddActiveParticipation(final User student, final FinalSeminar finalSeminar, final Project project) {
return canActiveParticipate(student, finalSeminar).map(allowed ->
createAndSaveActiveParticipation(student, finalSeminar, project)
);
}
@Override
@Transactional
public Either<ParticipateError, FinalSeminarActiveParticipation> attemptAddActiveParticipationAsSupervisor(User student, FinalSeminar finalSeminar, Project project) {
public Either<ParticipateError, FinalSeminarActiveParticipation> attemptAddActiveParticipationAsSupervisor(
User student,
FinalSeminar finalSeminar,
Project project
) {
if (alreadyActiveParticipant(student, finalSeminar)) {
return Either.left(ParticipateError.ALREADY_PARTICIPANT);
} else if (alreadyOpponent(student, finalSeminar)) {
@ -320,7 +359,11 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
}
}
private FinalSeminarActiveParticipation createAndSaveActiveParticipation(User student, FinalSeminar finalSeminar, Project project) {
private FinalSeminarActiveParticipation createAndSaveActiveParticipation(
User student,
FinalSeminar finalSeminar,
Project project
) {
FinalSeminarActiveParticipation activeParticipation = new FinalSeminarActiveParticipation();
activeParticipation.setUser(student);
activeParticipation.setFinalSeminar(finalSeminar);
@ -337,7 +380,10 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
@Override
public Date thesisUploadDeadline(FinalSeminar finalSeminar) {
return daysService.workDaysAhead(finalSeminar.getStartDate(), finalSeminarSettingsService.getInstance().getDaysAheadToUploadThesis());
return daysService.workDaysAhead(
finalSeminar.getStartDate(),
finalSeminarSettingsService.getInstance().getDaysAheadToUploadThesis()
);
}
@Override
@ -348,7 +394,7 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
@Override
public boolean hasThesis(FinalSeminar finalSeminar) {
FileReference fileDescription = finalSeminar.getDocument();
return fileDescription != null && fileService.isDataAvailable(fileDescription);
return (fileDescription != null && fileService.isDataAvailable(fileDescription));
}
@Override
@ -393,7 +439,6 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
return bb;
}
private BooleanExpression hasHeadSupervisor(User headSupervisor) {
return QFinalSeminar.finalSeminar.project.headSupervisor.eq(headSupervisor);
}
@ -430,7 +475,8 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
@Override
public List<FinalSeminarOpposition> getOppositionsByProjectAuthors(Project project) {
return project.getProjectParticipants()
return project
.getProjectParticipants()
.stream()
.map(author -> findFinalSeminarOppositionsByOpponentAndProjectType(project.getProjectType(), author))
.flatMap(List::stream)
@ -440,7 +486,7 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
@Override
public boolean hasHadFinalSeminar(Project project) {
FinalSeminar finalSeminar = findByProject(project);
return finalSeminar != null && finalSeminar.getStartDate().toInstant().isBefore(clock.instant());
return (finalSeminar != null && finalSeminar.getStartDate().toInstant().isBefore(clock.instant()));
}
@Override
@ -463,39 +509,52 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
}
@Override
public List<FinalSeminarOpposition> findFinalSeminarOppositionsByOpponentAndProjectType(ProjectType projectType, User user) {
public List<FinalSeminarOpposition> findFinalSeminarOppositionsByOpponentAndProjectType(
ProjectType projectType,
User user
) {
return finalSeminarOppositionRepository.findByOpposingUserAndType(user, projectType);
}
@Override
public List<FinalSeminarActiveParticipation> findUserParticipating(Project project, User user) {
return finalSeminarActiveParticipationRepository.findByParticipatingUserAndLevel(user, project.getProjectType());
return finalSeminarActiveParticipationRepository.findByParticipatingUserAndLevel(
user,
project.getProjectType()
);
}
@Override
public boolean isSubscribedToSeminarCreationNotifications(Project project, User user) {
final Optional<Author> author = authorRepository.findByProjectAndUser(project, user);
return author.isPresent() && author.get().isSubscribedToFinalSeminarNotifications();
return (author.isPresent() && author.get().isSubscribedToFinalSeminarNotifications());
}
@Override
@Transactional
public void toggleSubscriptionToSeminarCreationNotifications(Project project, User user) {
authorRepository.findByProjectAndUser(project, user)
.ifPresent(author -> author.setSubscribedToFinalSeminarNotifications(!author.isSubscribedToFinalSeminarNotifications()));
authorRepository
.findByProjectAndUser(project, user)
.ifPresent(author ->
author.setSubscribedToFinalSeminarNotifications(!author.isSubscribedToFinalSeminarNotifications())
);
}
private BooleanExpression unfinishedSeminars(Date after, Date before) {
QFinalSeminar seminar = QFinalSeminar.finalSeminar;
if (after == null && before == null) {
return seminar.oppositions.any().grade.isNull().or(
seminar.activeParticipations.any().grade.isNull().or(
seminar.respondents.any().grade.isNull()));
return seminar.oppositions
.any()
.grade.isNull()
.or(seminar.activeParticipations.any().grade.isNull().or(seminar.respondents.any().grade.isNull()));
} else {
return seminar.startDate.between(after, before)
.andAnyOf(seminar.oppositions.any().grade.isNull(),
return seminar.startDate
.between(after, before)
.andAnyOf(
seminar.oppositions.any().grade.isNull(),
seminar.activeParticipations.any().grade.isNull(),
seminar.respondents.any().grade.isNull());
seminar.respondents.any().grade.isNull()
);
}
}

@ -1,14 +1,14 @@
package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.system.DomainObject;
import jakarta.persistence.*;
import java.util.Objects;
import se.su.dsv.scipro.system.DomainObject;
@Entity
@Cacheable(true)
@Table(name = "final_seminar_settings")
public class FinalSeminarSettings extends DomainObject {
public static final int DEFAULT_DAYS_AHEAD_TO_UPLOAD_THESIS = 10;
public static final int DEFAULT_DAYS_AHEAD_TO_REGISTER_OPPOSITION = 3;
public static final int DEFAULT_DAYS_AHEAD_TO_REGISTER_PARTICIPATION = 1;
@ -16,8 +16,7 @@ public class FinalSeminarSettings extends DomainObject {
@Id
private Long id = null;
public FinalSeminarSettings() {
}
public FinalSeminarSettings() {}
public FinalSeminarSettings(final Long id) {
this.id = id;
@ -116,7 +115,25 @@ public class FinalSeminarSettings extends DomainObject {
@Override
public String toString() {
return "FinalSeminarSettings(id=" + this.getId() + ", daysAheadToCreate=" + this.getDaysAheadToCreate() + ", daysAheadToRegisterParticipation=" + this.getDaysAheadToRegisterParticipation() + ", daysAheadToRegisterOpposition=" + this.getDaysAheadToRegisterOpposition() + ", daysAheadToUploadThesis=" + this.getDaysAheadToUploadThesis() + ", thesisMustBePDF=" + this.isThesisMustBePDF() + ", evaluationURL=" + this.getEvaluationURL() + ", oppositionPriorityDays=" + this.getOppositionPriorityDays() + ")";
return (
"FinalSeminarSettings(id=" +
this.getId() +
", daysAheadToCreate=" +
this.getDaysAheadToCreate() +
", daysAheadToRegisterParticipation=" +
this.getDaysAheadToRegisterParticipation() +
", daysAheadToRegisterOpposition=" +
this.getDaysAheadToRegisterOpposition() +
", daysAheadToUploadThesis=" +
this.getDaysAheadToUploadThesis() +
", thesisMustBePDF=" +
this.isThesisMustBePDF() +
", evaluationURL=" +
this.getEvaluationURL() +
", oppositionPriorityDays=" +
this.getOppositionPriorityDays() +
")"
);
}
@Override
@ -124,16 +141,18 @@ public class FinalSeminarSettings extends DomainObject {
if (o == this) return true;
if (!(o instanceof FinalSeminarSettings)) return false;
final FinalSeminarSettings other = (FinalSeminarSettings) o;
return other.canEqual(this)
&& super.equals(o)
&& Objects.equals(this.getId(), other.getId())
&& this.getDaysAheadToCreate() == other.getDaysAheadToCreate()
&& this.getDaysAheadToRegisterParticipation() == other.getDaysAheadToRegisterParticipation()
&& this.getDaysAheadToRegisterOpposition() == other.getDaysAheadToRegisterOpposition()
&& this.getDaysAheadToUploadThesis() == other.getDaysAheadToUploadThesis()
&& this.isThesisMustBePDF() == other.isThesisMustBePDF()
&& Objects.equals(this.getEvaluationURL(), other.getEvaluationURL())
&& this.getOppositionPriorityDays() == other.getOppositionPriorityDays();
return (
other.canEqual(this) &&
super.equals(o) &&
Objects.equals(this.getId(), other.getId()) &&
this.getDaysAheadToCreate() == other.getDaysAheadToCreate() &&
this.getDaysAheadToRegisterParticipation() == other.getDaysAheadToRegisterParticipation() &&
this.getDaysAheadToRegisterOpposition() == other.getDaysAheadToRegisterOpposition() &&
this.getDaysAheadToUploadThesis() == other.getDaysAheadToUploadThesis() &&
this.isThesisMustBePDF() == other.isThesisMustBePDF() &&
Objects.equals(this.getEvaluationURL(), other.getEvaluationURL()) &&
this.getOppositionPriorityDays() == other.getOppositionPriorityDays()
);
}
protected boolean canEqual(final Object other) {
@ -150,6 +169,7 @@ public class FinalSeminarSettings extends DomainObject {
this.getDaysAheadToUploadThesis(),
this.isThesisMustBePDF(),
this.getEvaluationURL(),
this.getOppositionPriorityDays());
this.getOppositionPriorityDays()
);
}
}

@ -1,13 +1,14 @@
package se.su.dsv.scipro.finalseminar;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractServiceImpl;
public class FinalSeminarSettingsServiceImpl extends AbstractServiceImpl<FinalSeminarSettings,Long> implements FinalSeminarSettingsService {
public class FinalSeminarSettingsServiceImpl
extends AbstractServiceImpl<FinalSeminarSettings, Long>
implements FinalSeminarSettingsService {
private static final long INSTANCE_ID = 1L;

@ -1,6 +1,7 @@
package se.su.dsv.scipro.finalseminar;
public final class FinalSeminarThesisDeletedEvent {
private final FinalSeminar finalSeminar;
public FinalSeminarThesisDeletedEvent(final FinalSeminar finalSeminar) {

@ -3,6 +3,7 @@ package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.project.Project;
public final class FinalSeminarThesisUploadedEvent {
private final FinalSeminar seminar;
public FinalSeminarThesisUploadedEvent(FinalSeminar seminar) {

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