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
@ -21,9 +21,9 @@ public class ApiController {
@GetMapping("/hello-world")
public String helloWorld(@RequestParam(value = "username", required = false) String username) {
String name = Optional.ofNullable(username)
.map(userService::findByUsername)
.map(User::getFullName)
.orElse("World");
.map(userService::findByUsername)
.map(User::getFullName)
.orElse("World");
return "Hello, " + name + "!";
}
}

@ -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();
@ -218,11 +218,11 @@ public class CoreConfig {
@Bean
public OAuthSettings oAuthSettings(
@Value("${oauth.uri}") String uri,
@Value("${oauth.redirectUri}") String redirectUri,
@Value("${oauth.clientId}") String clientId,
@Value("${oauth.clientSecret}") String clientSecret)
{
@Value("${oauth.uri}") String uri,
@Value("${oauth.redirectUri}") String redirectUri,
@Value("${oauth.clientId}") String clientId,
@Value("${oauth.clientSecret}") String clientSecret
) {
return new OAuthSettings(uri, redirectUri, clientId, clientSecret);
}
@ -233,10 +233,10 @@ public class CoreConfig {
@Bean
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.url}") final String baseUrl,
@Value("${daisy.api.username}") final String user,
@Value("${daisy.api.password}") final String password
) {
return new DaisyAPIImpl(baseUrl, user, password);
}
@ -252,24 +252,36 @@ public class CoreConfig {
@Bean
public FinalSeminarApprovalServiceImpl finalSeminarApprovalService(
Provider<EntityManager> em,
FileService fileDescriptionService,
EventBus eventBus,
DaysService daysService,
ReviewerDeadlineSettingsService reviewerDeadlineSettingsService)
{
return new FinalSeminarApprovalServiceImpl(em, fileDescriptionService, eventBus, daysService, reviewerDeadlineSettingsService);
Provider<EntityManager> em,
FileService fileDescriptionService,
EventBus eventBus,
DaysService daysService,
ReviewerDeadlineSettingsService reviewerDeadlineSettingsService
) {
return new FinalSeminarApprovalServiceImpl(
em,
fileDescriptionService,
eventBus,
daysService,
reviewerDeadlineSettingsService
);
}
@Bean
public RoughDraftApprovalServiceImpl roughDraftApprovalService(
Provider<EntityManager> em,
FileService fileDescriptionService,
EventBus eventBus,
DaysService daysService,
ReviewerDeadlineSettingsService reviewerDeadlineSettingsService)
{
return new RoughDraftApprovalServiceImpl(em, eventBus, fileDescriptionService, daysService, reviewerDeadlineSettingsService);
Provider<EntityManager> em,
FileService fileDescriptionService,
EventBus eventBus,
DaysService daysService,
ReviewerDeadlineSettingsService reviewerDeadlineSettingsService
) {
return new RoughDraftApprovalServiceImpl(
em,
eventBus,
fileDescriptionService,
daysService,
reviewerDeadlineSettingsService
);
}
@Bean
@ -289,15 +301,19 @@ public class CoreConfig {
@Bean
public ActivityPlanFacadeImpl activityPlanFacade(
EventBus eventBus,
ProjectFileService projectFileService,
ChecklistTemplateService checklistTemplateService,
DaysService daysService,
FileService fileService
)
{
return new ActivityPlanFacadeImpl(eventBus, projectFileService, checklistTemplateService, daysService,
fileService);
EventBus eventBus,
ProjectFileService projectFileService,
ChecklistTemplateService checklistTemplateService,
DaysService daysService,
FileService fileService
) {
return new ActivityPlanFacadeImpl(
eventBus,
projectFileService,
checklistTemplateService,
daysService,
fileService
);
}
@Bean
@ -321,23 +337,25 @@ public class CoreConfig {
}
@Bean
public LocalAuthentication localAuthentication(
UserService userService,
PasswordService passwordService)
{
public LocalAuthentication localAuthentication(UserService userService, PasswordService passwordService) {
return new LocalAuthentication(userService, passwordService);
}
@Bean
public BasicForumServiceImpl basicForumService(
ForumPostRepository forumPostRepository,
ForumPostReadStateRepository readStateRepository,
AbstractThreadRepository threadRepository,
FileService fileService,
EventBus eventBus)
{
return new BasicForumServiceImpl(forumPostRepository, readStateRepository, threadRepository, fileService,
eventBus);
ForumPostRepository forumPostRepository,
ForumPostReadStateRepository readStateRepository,
AbstractThreadRepository threadRepository,
FileService fileService,
EventBus eventBus
) {
return new BasicForumServiceImpl(
forumPostRepository,
readStateRepository,
threadRepository,
fileService,
eventBus
);
}
@Bean
@ -372,9 +390,9 @@ public class CoreConfig {
@Bean
public DeliveryConfigurationServiceImpl deliveryConfigurationService(
Provider<EntityManager> em,
UserProfileService userProfileService)
{
Provider<EntityManager> em,
UserProfileService userProfileService
) {
return new DeliveryConfigurationServiceImpl(em, userProfileService);
}
@ -395,16 +413,18 @@ public class CoreConfig {
@Bean
public FileServiceImpl fileService(
Provider<EntityManager> em,
FileStore fileStore,
FileReferenceRepository fileReferenceRepository,
FileDescriptionRepo fileDescriptionRepository)
{
Provider<EntityManager> em,
FileStore fileStore,
FileReferenceRepository fileReferenceRepository,
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);
}
@ -420,26 +440,27 @@ public class CoreConfig {
@Bean
public FinalSeminarServiceImpl finalSeminarService(
Provider<EntityManager> em,
EventBus eventBus,
FileService fileService,
AuthorRepository authorRepository,
FinalSeminarOppositionRepo finalSeminarOppositionRepository,
FinalSeminarActiveParticipationRepository finalSeminarActiveParticipationRepository,
FinalSeminarRepository finalSeminarRepository,
Clock clock,
RoughDraftApprovalService roughDraftApprovalService)
{
Provider<EntityManager> em,
EventBus eventBus,
FileService fileService,
AuthorRepository authorRepository,
FinalSeminarOppositionRepo finalSeminarOppositionRepository,
FinalSeminarActiveParticipationRepository finalSeminarActiveParticipationRepository,
FinalSeminarRepository finalSeminarRepository,
Clock clock,
RoughDraftApprovalService roughDraftApprovalService
) {
return new FinalSeminarServiceImpl(
em,
eventBus,
authorRepository,
fileService,
finalSeminarOppositionRepository,
finalSeminarActiveParticipationRepository,
finalSeminarRepository,
clock,
roughDraftApprovalService);
em,
eventBus,
authorRepository,
fileService,
finalSeminarOppositionRepository,
finalSeminarActiveParticipationRepository,
finalSeminarRepository,
clock,
roughDraftApprovalService
);
}
@Bean
@ -449,37 +470,51 @@ public class CoreConfig {
@Bean
public FinalSeminarUploadControllerImpl finalSeminarUploadController(
EventBus eventBus,
FileService fileService,
FinalSeminarService finalSeminarService,
ProjectFileService projectFileService,
ProjectService projectService,
FinalSeminarSettingsService finalSeminarSettingsService,
PlagiarismControl plagiarismControl)
{
return new FinalSeminarUploadControllerImpl(projectService, fileService, finalSeminarSettingsService,
finalSeminarService, eventBus, projectFileService, plagiarismControl);
EventBus eventBus,
FileService fileService,
FinalSeminarService finalSeminarService,
ProjectFileService projectFileService,
ProjectService projectService,
FinalSeminarSettingsService finalSeminarSettingsService,
PlagiarismControl plagiarismControl
) {
return new FinalSeminarUploadControllerImpl(
projectService,
fileService,
finalSeminarSettingsService,
finalSeminarService,
eventBus,
projectFileService,
plagiarismControl
);
}
@Bean
public FinalThesisServiceImpl finalThesisService(
Provider<EntityManager> em,
NotificationController notification,
ProjectFileService projectFile,
FileService fileService,
EventBus eventBus,
PlagiarismControl plagiarismControl,
GradingReportService gradingReportService)
{
return new FinalThesisServiceImpl(em, notification, projectFile,
fileService, eventBus, plagiarismControl, gradingReportService);
Provider<EntityManager> em,
NotificationController notification,
ProjectFileService projectFile,
FileService fileService,
EventBus eventBus,
PlagiarismControl plagiarismControl,
GradingReportService gradingReportService
) {
return new FinalThesisServiceImpl(
em,
notification,
projectFile,
fileService,
eventBus,
plagiarismControl,
gradingReportService
);
}
@Bean
public FirstMeetingServiceImpl firstMeetingService(
Provider<EntityManager> em,
ActivityPlanFacade activityPlanFacade)
{
Provider<EntityManager> em,
ActivityPlanFacade activityPlanFacade
) {
return new FirstMeetingServiceImpl(em, activityPlanFacade);
}
@ -500,28 +535,29 @@ public class CoreConfig {
@Bean
public GradingReportServiceImpl gradingReportService(
EventBus eventBus,
ThesisSubmissionHistoryService thesisSubmissionHistoryService,
Clock clock,
SupervisorGradingReportRepository supervisorGradingReportRepository,
GradingReportTemplateRepoImpl gradingReportTemplateRepo,
ProjectTypeService projectTypeService)
{
EventBus eventBus,
ThesisSubmissionHistoryService thesisSubmissionHistoryService,
Clock clock,
SupervisorGradingReportRepository supervisorGradingReportRepository,
GradingReportTemplateRepoImpl gradingReportTemplateRepo,
ProjectTypeService projectTypeService
) {
return new GradingReportServiceImpl(
eventBus,
thesisSubmissionHistoryService,
clock,
supervisorGradingReportRepository,
gradingReportTemplateRepo,
projectTypeService);
eventBus,
thesisSubmissionHistoryService,
clock,
supervisorGradingReportRepository,
gradingReportTemplateRepo,
projectTypeService
);
}
@Bean
public GroupForumServiceImpl groupForumService(
EventBus eventBus,
GroupThreadRepository groupThreadRepository,
BasicForumService basicForumService)
{
EventBus eventBus,
GroupThreadRepository groupThreadRepository,
BasicForumService basicForumService
) {
return new GroupForumServiceImpl(groupThreadRepository, basicForumService, eventBus);
}
@ -532,18 +568,27 @@ public class CoreConfig {
@Bean
public IdeaServiceImpl ideaService(
Provider<EntityManager> em,
ApplicationPeriodService applicationPeriodService,
FirstMeetingRepository firstMeetingRepository,
NotificationController notificationController,
ProjectService projectService,
GeneralSystemSettingsService generalSystemSettingsService,
TargetRepository targetRepository,
IdeaRepository ideaRepository,
Clock clock)
{
return new IdeaServiceImpl(em, applicationPeriodService, firstMeetingRepository, notificationController,
projectService, generalSystemSettingsService, targetRepository, ideaRepository, clock);
Provider<EntityManager> em,
ApplicationPeriodService applicationPeriodService,
FirstMeetingRepository firstMeetingRepository,
NotificationController notificationController,
ProjectService projectService,
GeneralSystemSettingsService generalSystemSettingsService,
TargetRepository targetRepository,
IdeaRepository ideaRepository,
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);
}
@ -585,9 +630,9 @@ public class CoreConfig {
@Bean
public MilestoneServiceImpl milestoneService(
Provider<EntityManager> em,
NotificationController notificationController)
{
Provider<EntityManager> em,
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);
}
@ -620,13 +665,17 @@ public class CoreConfig {
@Bean
public OppositionReportServiceImpl oppositionReportService(
OppositionReportRepo oppositionReportRepository,
GradingReportTemplateRepo gradingReportTemplateRepository,
FileService fileService,
FinalSeminarOppositionRepo finalSeminarOppositionRepository)
{
return new OppositionReportServiceImpl(oppositionReportRepository, gradingReportTemplateRepository,
fileService, finalSeminarOppositionRepository);
OppositionReportRepo oppositionReportRepository,
GradingReportTemplateRepo gradingReportTemplateRepository,
FileService fileService,
FinalSeminarOppositionRepo finalSeminarOppositionRepository
) {
return new OppositionReportServiceImpl(
oppositionReportRepository,
gradingReportTemplateRepository,
fileService,
finalSeminarOppositionRepository
);
}
@Bean
@ -636,41 +685,48 @@ public class CoreConfig {
@Bean
public PeerPortalImpl peerPortal(
FileService fileService,
PeerReviewRepository peerReviewRepository,
PeerRequestRepository peerRequestRepository,
EventBus eventBus,
ProjectFileService projectFileService,
DaysService daisyService,
Clock clock)
{
return new PeerPortalImpl(fileService, peerReviewRepository, peerRequestRepository,
eventBus, projectFileService, daisyService, clock);
FileService fileService,
PeerReviewRepository peerReviewRepository,
PeerRequestRepository peerRequestRepository,
EventBus eventBus,
ProjectFileService projectFileService,
DaysService daisyService,
Clock clock
) {
return new PeerPortalImpl(
fileService,
peerReviewRepository,
peerRequestRepository,
eventBus,
projectFileService,
daisyService,
clock
);
}
@Bean
public PeerRequestServiceImpl peerRequestService(
Provider<EntityManager> em,
EventBus eventBus,
FileService fileService)
{
Provider<EntityManager> em,
EventBus eventBus,
FileService fileService
) {
return new PeerRequestServiceImpl(em, eventBus, fileService);
}
@Bean
public PeerReviewServiceImpl peerReviewService(
Provider<EntityManager> em,
PeerReviewRepository peerReviewRepository)
{
Provider<EntityManager> em,
PeerReviewRepository peerReviewRepository
) {
return new PeerReviewServiceImpl(em, peerReviewRepository);
}
@Bean
public PlagiarismControlImpl plagiarismControl(
FileService fileService,
PlagiarismRequestRepository plagiarismRequestRepository,
UrkundSubmissionRepository urkundSubmissionRepository)
{
FileService fileService,
PlagiarismRequestRepository plagiarismRequestRepository,
UrkundSubmissionRepository urkundSubmissionRepository
) {
return new PlagiarismControlImpl(plagiarismRequestRepository, urkundSubmissionRepository, fileService);
}
@ -686,9 +742,9 @@ public class CoreConfig {
@Bean
public ProjectFileServiceImpl projectFileService(
FileService fileService,
ProjectFileRepository projectFileRepository)
{
FileService fileService,
ProjectFileRepository projectFileRepository
) {
return new ProjectFileServiceImpl(fileService, projectFileRepository);
}
@ -699,14 +755,19 @@ public class CoreConfig {
@Bean
public ProjectForumServiceImpl projectForumService(
EventBus eventBus,
BasicForumService basicForumService,
ProjectThreadRepository projectThreadRepository,
ForumPostRepository postRepository,
ProjectFileService projectFileService)
{
return new ProjectForumServiceImpl(projectThreadRepository,
postRepository, projectFileService, basicForumService, eventBus);
EventBus eventBus,
BasicForumService basicForumService,
ProjectThreadRepository projectThreadRepository,
ForumPostRepository postRepository,
ProjectFileService projectFileService
) {
return new ProjectForumServiceImpl(
projectThreadRepository,
postRepository,
projectFileService,
basicForumService,
eventBus
);
}
@Bean
@ -721,11 +782,11 @@ public class CoreConfig {
@Bean
public ProjectServiceImpl projectService(
Provider<EntityManager> em,
EventBus eventBus,
ProjectRepo projectRepo,
Clock clock)
{
Provider<EntityManager> em,
EventBus eventBus,
ProjectRepo projectRepo,
Clock clock
) {
return new ProjectServiceImpl(projectRepo, clock, eventBus, em);
}
@ -736,17 +797,17 @@ public class CoreConfig {
@Bean
public PublicationMetadataServiceImpl publicationMetadataService(
PublicationMetadataRepository publicationMetadataRepository)
{
PublicationMetadataRepository publicationMetadataRepository
) {
return new PublicationMetadataServiceImpl(publicationMetadataRepository);
}
@Bean
public ReflectionServiceImpl reflectionService(
AuthorRepository authorRepository,
FinalSeminarServiceImpl finalSeminarService,
EventBus eventBus)
{
AuthorRepository authorRepository,
FinalSeminarServiceImpl finalSeminarService,
EventBus eventBus
) {
return new ReflectionServiceImpl(authorRepository, finalSeminarService, eventBus);
}
@ -762,23 +823,35 @@ public class CoreConfig {
@Bean
public ZipReporter reporter(
FileService fileService,
ProjectService projectService,
FinalSeminarService finalSeminarService,
ProjectForumService projectForumService,
PeerReviewService peerReviewService,
PeerRequestService peerRequestService,
GroupService groupService,
GroupForumService groupForumService,
IdeaService ideaService,
GradingReportService gradingReportService,
ReviewerInteractionService reviewerInteractionService,
RoughDraftApprovalService roughDraftApprovalService,
FinalSeminarApprovalService finalSeminarApprovalService)
{
return new ZipReporter(fileService, projectService, finalSeminarService, projectForumService, peerReviewService,
peerRequestService, groupService, groupForumService, ideaService, gradingReportService,
reviewerInteractionService, roughDraftApprovalService, finalSeminarApprovalService);
FileService fileService,
ProjectService projectService,
FinalSeminarService finalSeminarService,
ProjectForumService projectForumService,
PeerReviewService peerReviewService,
PeerRequestService peerRequestService,
GroupService groupService,
GroupForumService groupForumService,
IdeaService ideaService,
GradingReportService gradingReportService,
ReviewerInteractionService reviewerInteractionService,
RoughDraftApprovalService roughDraftApprovalService,
FinalSeminarApprovalService finalSeminarApprovalService
) {
return new ZipReporter(
fileService,
projectService,
finalSeminarService,
projectForumService,
peerReviewService,
peerRequestService,
groupService,
groupForumService,
ideaService,
gradingReportService,
reviewerInteractionService,
roughDraftApprovalService,
finalSeminarApprovalService
);
}
@Bean
@ -793,38 +866,43 @@ public class CoreConfig {
@Bean
public ReviewerInteractionServiceImpl reviewerInteractionService(
ReviewerThreadRepository reviewerThreadRepository,
BasicForumService forumService,
EventBus eventBus)
{
ReviewerThreadRepository reviewerThreadRepository,
BasicForumService forumService,
EventBus eventBus
) {
return new ReviewerInteractionServiceImpl(reviewerThreadRepository, forumService, eventBus);
}
@Bean
public ReviewingServiceImpl reviewingService(
Provider<EntityManager> em,
EventBus eventBus,
FileService fileService)
{
Provider<EntityManager> em,
EventBus eventBus,
FileService fileService
) {
return new ReviewingServiceImpl(em, fileService, eventBus);
}
@Bean
public ReviewerCapacityServiceImpl reviewerCapacityService(
ReviewerTargetRepository reviewerTargetRepository,
DecisionRepository decisionRepository,
UserService userService,
ProjectService projectService,
EventBus eventBus)
{
return new ReviewerCapacityServiceImpl(reviewerTargetRepository, decisionRepository, userService,
projectService, eventBus);
ReviewerTargetRepository reviewerTargetRepository,
DecisionRepository decisionRepository,
UserService userService,
ProjectService projectService,
EventBus eventBus
) {
return new ReviewerCapacityServiceImpl(
reviewerTargetRepository,
decisionRepository,
userService,
projectService,
eventBus
);
}
@Bean
public ReviewerDeadlineSettingsServiceImpl reviewerDeadlineSettingsService(
ReviewerDeadlineSettingsRepository reviewerDeadlineSettingsRepository)
{
ReviewerDeadlineSettingsRepository reviewerDeadlineSettingsRepository
) {
return new ReviewerDeadlineSettingsServiceImpl(reviewerDeadlineSettingsRepository);
}
@ -835,14 +913,19 @@ public class CoreConfig {
@Bean
public SurveyServiceImpl surveyService(
SurveyRepository surveyRepository,
QuestionRepository questionRepository,
FinalThesisService finalThesisService,
GeneralSystemSettingsService generalSystemSettingsService,
ReflectionService reflectionService)
{
return new SurveyServiceImpl(surveyRepository, questionRepository, finalThesisService,
generalSystemSettingsService, reflectionService);
SurveyRepository surveyRepository,
QuestionRepository questionRepository,
FinalThesisService finalThesisService,
GeneralSystemSettingsService generalSystemSettingsService,
ReflectionService reflectionService
) {
return new SurveyServiceImpl(
surveyRepository,
questionRepository,
finalThesisService,
generalSystemSettingsService,
reflectionService
);
}
@Bean
@ -856,20 +939,17 @@ public class CoreConfig {
}
@Bean
public UrkundApiImpl urkundApi(
UrkundSettingsRepository urkundSettingsRepository,
FileService fileService)
{
public UrkundApiImpl urkundApi(UrkundSettingsRepository urkundSettingsRepository, FileService fileService) {
return new UrkundApiImpl(urkundSettingsRepository, fileService);
}
@Bean
public UrkundServiceImpl urkundService(
UrkundApi urkundApi,
UrkundSubmissionRepository urkundSubmissionRepository,
Sukat sukat,
FileService fileService)
{
UrkundApi urkundApi,
UrkundSubmissionRepository urkundSubmissionRepository,
Sukat sukat,
FileService fileService
) {
return new UrkundServiceImpl(urkundApi, urkundSubmissionRepository, sukat, fileService);
}
@ -895,16 +975,21 @@ public class CoreConfig {
@Bean
public NotificationControllerImpl notificationController(
NotificationServiceImpl notificationService,
NotificationMailFormatter notificationMailFormatter,
MailEventService mailEventService,
ReceiverConfigurationService receiverConfigurationService,
DeliveryConfigurationService deliveryConfigurationService,
Provider<CurrentUser> currentUserProvider)
{
return new NotificationControllerImpl(notificationService,
notificationMailFormatter,
mailEventService, receiverConfigurationService, deliveryConfigurationService, currentUserProvider);
NotificationServiceImpl notificationService,
NotificationMailFormatter notificationMailFormatter,
MailEventService mailEventService,
ReceiverConfigurationService receiverConfigurationService,
DeliveryConfigurationService deliveryConfigurationService,
Provider<CurrentUser> currentUserProvider
) {
return new NotificationControllerImpl(
notificationService,
notificationMailFormatter,
mailEventService,
receiverConfigurationService,
deliveryConfigurationService,
currentUserProvider
);
}
@Bean
@ -914,15 +999,21 @@ public class CoreConfig {
@Bean
public ReviewerAssignedDeadline reviewerAssignedDeadline(
EventBus eventBus,
ReviewerDeadlineSettingsService reviewerDeadlineSettingsService,
RoughDraftApprovalService roughDraftApprovalService,
FinalSeminarApprovalService finalSeminarApprovalService,
DaysService daysService,
Clock clock)
{
return new ReviewerAssignedDeadline(roughDraftApprovalService, finalSeminarApprovalService,
reviewerDeadlineSettingsService, daysService, eventBus, clock);
EventBus eventBus,
ReviewerDeadlineSettingsService reviewerDeadlineSettingsService,
RoughDraftApprovalService roughDraftApprovalService,
FinalSeminarApprovalService finalSeminarApprovalService,
DaysService daysService,
Clock clock
) {
return new ReviewerAssignedDeadline(
roughDraftApprovalService,
finalSeminarApprovalService,
reviewerDeadlineSettingsService,
daysService,
eventBus,
clock
);
}
@Bean
@ -932,53 +1023,67 @@ public class CoreConfig {
@Bean
public FinalSeminarActivityHandler finalSeminarActivityHandler(
ActivityPlanFacade activityPlanFacade,
ActivityFinalSeminarRepository activityFinalSeminarRepository,
EventBus eventBus)
{
ActivityPlanFacade activityPlanFacade,
ActivityFinalSeminarRepository activityFinalSeminarRepository,
EventBus eventBus
) {
return new FinalSeminarActivityHandler(activityPlanFacade, activityFinalSeminarRepository, eventBus);
}
@Bean
public PostActivityUploadToForum postActivityUploadToForum(
EventBus eventBus,
ProjectForumService projectForumService,
ActivityThreadRepository activityThreadRepository)
{
EventBus eventBus,
ProjectForumService projectForumService,
ActivityThreadRepository activityThreadRepository
) {
return new PostActivityUploadToForum(projectForumService, activityThreadRepository, eventBus);
}
@Bean
public ForumNotifications forumNotifications(
EventBus eventBus,
NotificationController notificationController,
ForumNotificationRepository forumNotificationRepository,
NotificationService notificationService)
{
return new ForumNotifications(eventBus, notificationController, forumNotificationRepository,
notificationService);
EventBus eventBus,
NotificationController notificationController,
ForumNotificationRepository forumNotificationRepository,
NotificationService notificationService
) {
return new ForumNotifications(
eventBus,
notificationController,
forumNotificationRepository,
notificationService
);
}
@Bean
public ActivateCompletedMilestonesOnNewProjects activateCompletedMilestonesOnNewProjects(
EventBus eventBus,
MilestoneServiceImpl milestoneService,
PeerReviewService peerReviewService,
MilestoneActivityTemplateService milestoneActivityTemplateService,
FinalSeminarService finalSeminarService)
{
return new ActivateCompletedMilestonesOnNewProjects(peerReviewService, milestoneActivityTemplateService,
milestoneService, eventBus, finalSeminarService);
EventBus eventBus,
MilestoneServiceImpl milestoneService,
PeerReviewService peerReviewService,
MilestoneActivityTemplateService milestoneActivityTemplateService,
FinalSeminarService finalSeminarService
) {
return new ActivateCompletedMilestonesOnNewProjects(
peerReviewService,
milestoneActivityTemplateService,
milestoneService,
eventBus,
finalSeminarService
);
}
@Bean
public FinalSeminarCreationSubscribers finalSeminarCreationSubscribers(
EventBus eventBus,
FinalSeminarServiceImpl finalSeminarService,
NotificationController notificationController,
AuthorRepository authorRepository)
{
return new FinalSeminarCreationSubscribers(authorRepository, finalSeminarService, notificationController, eventBus);
EventBus eventBus,
FinalSeminarServiceImpl finalSeminarService,
NotificationController notificationController,
AuthorRepository authorRepository
) {
return new FinalSeminarCreationSubscribers(
authorRepository,
finalSeminarService,
notificationController,
eventBus
);
}
@Bean
@ -988,18 +1093,18 @@ public class CoreConfig {
@Bean
public AddActivityPlanOnProjectStart addActivityPlanOnProjectStart(
ActivityPlanFacade activityPlanFacade,
EventBus eventBus)
{
ActivityPlanFacade activityPlanFacade,
EventBus eventBus
) {
return new AddActivityPlanOnProjectStart(activityPlanFacade, eventBus);
}
@Bean
public Notifications notifications(
EventBus eventBus,
NotificationController notificationController,
NotificationService notificationService)
{
EventBus eventBus,
NotificationController notificationController,
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,51 +1,48 @@
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")
@Cacheable(true)
public class Activity extends LazyDeletableDomainObject {
public static IActivityPlan builder(){
public static IActivityPlan builder() {
return new Builder();
}
//<editor-fold desc="Basic JPA-mappings">
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Basic
@Column(name = "title", nullable=false)
@Column(name = "title", nullable = false)
private String title;
@Basic
@Column(name = "date", nullable=false)
@Column(name = "date", nullable = false)
private Date date;
@Basic
@ -59,28 +56,31 @@ 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.">
@ManyToOne(optional = false)
@JoinColumn(name = "activity_plan_id", referencedColumnName = "id")
@JoinColumn(name = "activity_plan_id", referencedColumnName = "id")
@QueryInit("project")
private ActivityPlan activityPlan;
private ActivityPlan activityPlan;
@ManyToOne
@JoinColumn(name = "checklist_id", referencedColumnName = "id")
private Checklist checklist;
@OneToOne(optional = true, cascade = CascadeType.ALL)
@OneToOne(optional = true, cascade = CascadeType.ALL)
@JoinColumn(name = "upload_file_reference_id", referencedColumnName = "id")
private FileReference fileUpload;
private FileReference fileUpload;
//</editor-fold>
//<editor-fold desc="Constructor">
public Activity() {
this.title = "";
this.description = "";
}
public Activity() {
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
@ -174,19 +174,22 @@ public class Activity extends LazyDeletableDomainObject {
}
@Override
public String toString(){
return "Event: "+ getTitle()+"@"+getDate();
}
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;
@ -247,7 +251,7 @@ public class Activity extends LazyDeletableDomainObject {
}
public interface IDate {
IName date (Date date);
IName date(Date date);
}
public interface IName {

@ -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,18 +11,16 @@ 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")
@Table(name = "activity_plan")
@Cacheable(true)
public class ActivityPlan extends DomainObject {
@ -31,28 +29,31 @@ public class ActivityPlan extends DomainObject {
}
//<editor-fold desc="Basic JPA-mappings">
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@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)
@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());
@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)">
@Override
@Override
public Long getId() {
return this.id;
}
@ -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,
String name,
String description,
Action action,
final Date date,
final Checklist checklist,
final boolean editable) {
private Activity createNewActivity(
final ActivityPlan ps,
String name,
String description,
Action action,
final Date date,
final Checklist checklist,
final boolean editable
) {
Activity pse = new Activity();
pse.setActivityPlan(ps);
if (date == null) {
@ -106,16 +117,16 @@ 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(),
event.getDescription(),
event.getAction(),
event.getDate(),
event.getChecklist(),
event.isEditable());
event.getActivityPlan(),
event.getTitle(),
event.getDescription(),
event.getAction(),
event.getDate(),
event.getChecklist(),
event.isEditable()
);
}
return activityService.save(event);
}
@ -168,14 +179,20 @@ 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,
ActivityPlanTemplate template,
final Date startDate) {
ActivityPlanTemplate reloadedTemplate = activityPlanTemplateService.findOne(template.getId());//Reload lazily linked entities
private void addActivitiesFromTemplate(
final ActivityPlan schedule,
ActivityPlanTemplate template,
final Date startDate
) {
ActivityPlanTemplate reloadedTemplate = activityPlanTemplateService.findOne(template.getId()); //Reload lazily linked entities
int accumulatedOffset = 0;
for (final ActivityTemplate eventTemplate : reloadedTemplate.getActivityTemplates()) {
accumulatedOffset += eventTemplate.getDaysOffset();
@ -186,13 +203,14 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
final Action action = eventTemplate.getAction();
if (checklistTemplate != null) {
createNewActivity(
schedule,
title,
desc,
action,
dateForEvent,
createChecklist(schedule.getProject(), checklistTemplate),
true);
schedule,
title,
desc,
action,
dateForEvent,
createChecklist(schedule.getProject(), checklistTemplate),
true
);
} else {
createNewActivity(schedule, title, desc, action, dateForEvent, null, true);
}
@ -205,10 +223,11 @@ public class ActivityPlanFacadeImpl implements ActivityPlanFacade {
@Override
@Transactional
public ActivityPlanTemplate createTemplateFromSchedule(
final ActivityPlan schedule,
final User user,
final String name,
final String description) {
final ActivityPlan schedule,
final User user,
final String name,
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,14 +1,14 @@
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) {
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;
@ -29,134 +27,158 @@ import se.su.dsv.scipro.system.User;
@Cacheable(true)
public class ActivityPlanTemplate extends DomainObject {
//<editor-fold desc="Basic JPA-mappings">
//<editor-fold desc="Basic JPA-mappings">
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Basic
@Column(name = "is_sys_admin_template", nullable=false)
private boolean isSysAdminTemplate = false;
@Basic
@Column(name = "is_sys_admin_template", nullable = false)
private boolean isSysAdminTemplate = false;
@Basic
@Column(name = "title", nullable = false)
private String title;
@Basic
@Column(name = "title", nullable = false)
private String title;
@Basic
@Column(name = "description")
@Lob
private String description;
//</editor-fold>
@Basic
@Column(name = "description")
@Lob
private String description;
//<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>
//<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="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 desc="Properties (Getters and Setters)">
@Override
public Long getId() {
return this.id;
}
//</editor-fold>
public void setId(Long id) {
this.id = id;
}
//<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<>();
public boolean isSysAdminTemplate() {
return this.isSysAdminTemplate;
}
//</editor-fold>
public void setSysAdminTemplate(boolean isSysAdminTemplate) {
this.isSysAdminTemplate = isSysAdminTemplate;
}
//<editor-fold desc="Properties (Getters and Setters)">
@Override
public Long getId() {
return this.id;
}
public String getTitle() {
return this.title;
}
public void setId(Long id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public boolean isSysAdminTemplate() {
return this.isSysAdminTemplate;
}
public String getDescription() {
return this.description;
}
public void setSysAdminTemplate(boolean isSysAdminTemplate) {
this.isSysAdminTemplate = isSysAdminTemplate;
}
public void setDescription(String description) {
this.description = description;
}
public String getTitle() {
return this.title;
}
public User getCreator() {
return this.creator;
}
public void setTitle(String title) {
this.title = title;
}
public void setCreator(User creator) {
this.creator = creator;
}
public String getDescription() {
return this.description;
}
public List<ActivityTemplate> getActivityTemplates(){
return Collections.unmodifiableList(activityTemplates);
}
public void setDescription(String description) {
this.description = description;
}
public void setActivityTemplates(List<ActivityTemplate> activityTemplates){
this.activityTemplates = new ArrayList<>(activityTemplates);
}
//</editor-fold>
public User getCreator() {
return this.creator;
}
//<editor-fold desc="Methods Common To All Objects">
@Override
public boolean equals(final Object o) {
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();
}
public void setCreator(User creator) {
this.creator = creator;
}
protected boolean canEqual(final Object other) {
return other instanceof ActivityPlanTemplate;
}
public List<ActivityTemplate> getActivityTemplates() {
return Collections.unmodifiableList(activityTemplates);
}
@Override
public int hashCode() {
return Objects.hash(this.getId(), this.getActivityTemplates(), this.getCreator(), this.getTitle(), this.getDescription(), this.isSysAdminTemplate());
}
public void setActivityTemplates(List<ActivityTemplate> activityTemplates) {
this.activityTemplates = new ArrayList<>(activityTemplates);
}
@Override
public String toString() {
return "ActivityPlanTemplate(id=" + this.getId() + ", creator=" + this.getCreator() +
", title=" + this.getTitle() + ", description=" + this.getDescription() +
", isSysAdminTemplate=" + this.isSysAdminTemplate() + ")";
}
//</editor-fold>
//</editor-fold>
//<editor-fold desc="Other methods">
public void addActivity(ActivityTemplate activity){
activity.setActivityPlanTemplate(this);
activity.setNumberInOrder(activityTemplates.size());
activityTemplates.add(activity);
}
//<editor-fold desc="Methods Common To All Objects">
@Override
public boolean equals(final Object o) {
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()
);
}
public void clearActivities(){
activityTemplates.clear();
}
protected boolean canEqual(final Object other) {
return other instanceof ActivityPlanTemplate;
}
public void addActivities(final Collection<ActivityTemplate> activities){
activityTemplates.addAll(activities);
}
//</editor-fold>
@Override
public int hashCode() {
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() +
")"
);
}
//</editor-fold>
//<editor-fold desc="Other methods">
public void addActivity(ActivityTemplate activity) {
activity.setActivityPlanTemplate(this);
activity.setNumberInOrder(activityTemplates.size());
activityTemplates.add(activity);
}
public void clearActivities() {
activityTemplates.clear();
}
public void addActivities(final Collection<ActivityTemplate> activities) {
activityTemplates.addAll(activities);
}
//</editor-fold>
}

@ -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);
@ -31,23 +32,26 @@ public class ActivityPlanTemplateServiceImpl extends AbstractServiceImpl<Activit
protected static Predicate toPredicate(ActivityPlanTemplateService.Filter filter) {
BooleanBuilder predicate = new BooleanBuilder();
if (filter.getFilterString()!=null){
if (filter.getFilterString() != null) {
predicate.and(filterString(filter.getFilterString()));
}
if (filter.getCreator()!=null){
if (filter.getCreator() != null) {
predicate.and(creator(filter.getCreator()));
}
return predicate;
}
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)
.or(QActivityPlanTemplate.activityPlanTemplate.creator.firstName.containsIgnoreCase(filterString))
.or(QActivityPlanTemplate.activityPlanTemplate.creator.lastName.containsIgnoreCase(filterString));
return QActivityPlanTemplate.activityPlanTemplate.title
.containsIgnoreCase(filterString)
.or(QActivityPlanTemplate.activityPlanTemplate.creator.firstName.containsIgnoreCase(filterString))
.or(QActivityPlanTemplate.activityPlanTemplate.creator.lastName.containsIgnoreCase(filterString));
}
@Override

@ -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,26 +53,29 @@ public class Checklist extends DomainObject {
private Project project;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "checklist_checklist_question",
joinColumns = @JoinColumn(name = "checklist_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "checklist_question_id", referencedColumnName = "id"))
@JoinTable(
name = "checklist_checklist_question",
joinColumns = @JoinColumn(name = "checklist_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "checklist_question_id", referencedColumnName = "id")
)
private List<ChecklistQuestion> questions = new ArrayList<>();
@ManyToMany
@JoinTable(name = "checklist_checklist_category",
joinColumns = @JoinColumn(name = "checklist_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "checklist_category_id", referencedColumnName = "id"))
@JoinTable(
name = "checklist_checklist_category",
joinColumns = @JoinColumn(name = "checklist_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)
@CollectionTable(name = "checklist_user_last_open_date", joinColumns = @JoinColumn(name = "checklist_id"))
@Column(name = "last_open_date")
@SuppressWarnings("JpaDataSourceORMInspection") // false warning from IntelliJ for the @MapKeyJoinColumn
@SuppressWarnings("JpaDataSourceORMInspection") // false warning from IntelliJ for the @MapKeyJoinColumn
@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() +
")"
);
}
// ----------------------------------------------------------------------------------
@ -126,4 +132,4 @@ public class ChecklistAnswer extends DomainObject {
protected boolean canEqual(final Object other) {
return other instanceof ChecklistAnswer;
}
}
}

@ -1,9 +1,9 @@
package se.su.dsv.scipro.checklist;
public enum ChecklistAnswerEnum {
RED,
GREEN,
YELLOW,
NOT_APPLICABLE,
NO_ANSWER
RED,
GREEN,
YELLOW,
NOT_APPLICABLE,
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,64 +7,63 @@ 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")
@Table(name = "checklist_category")
@Cacheable(true)
public class ChecklistCategory extends DomainObject {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "category_name", unique = true)
private String categoryName;
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
protected ChecklistCategory() {
}
public ChecklistCategory(final String name){
categoryName = name;
}
@Column(name = "category_name", unique = true)
private String categoryName;
@Override
public Long getId() {
return this.id;
}
protected ChecklistCategory() {}
public String getCategoryName() {
return this.categoryName;
}
public ChecklistCategory(final String name) {
categoryName = name;
}
public void setId(Long id) {
this.id = id;
}
@Override
public Long getId() {
return this.id;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getCategoryName() {
return this.categoryName;
}
@Override
public String toString() {
return "ChecklistCategory(id=" + this.getId() + ", categoryName=" + this.getCategoryName() + ")";
}
public void setId(Long id) {
this.id = id;
}
@Override
public boolean equals(final Object o) {
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());
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
protected boolean canEqual(final Object other) {
return other instanceof ChecklistCategory;
}
@Override
public String toString() {
return ("ChecklistCategory(id=" + this.getId() + ", categoryName=" + this.getCategoryName() + ")");
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
}
@Override
public boolean equals(final Object o) {
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()));
}
protected boolean canEqual(final Object other) {
return other instanceof ChecklistCategory;
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
}
}

@ -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;
@ -39,13 +38,13 @@ public class ChecklistQuestion extends DomainObject {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(
name = "checklist_question_checklist_answer",
joinColumns = @JoinColumn(name = "checklist_question_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "checklist_answer_id", referencedColumnName = "id"))
name = "checklist_question_checklist_answer",
joinColumns = @JoinColumn(name = "checklist_question_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) {
@ -124,4 +132,4 @@ public class ChecklistQuestion extends DomainObject {
public int hashCode() {
return Objects.hashCode(this.getId());
}
}
}

@ -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);
@ -22,33 +21,31 @@ public class ChecklistServiceImpl extends AbstractServiceImpl<Checklist, Long> i
@Override
public Long countAnswers(Project project, ChecklistAnswerEnum answer) {
return from(QActivityPlan.activityPlan)
.select(QChecklistAnswer.checklistAnswer.count())
.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))
.fetchFirst();
.select(QChecklistAnswer.checklistAnswer.count())
.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))
.fetchFirst();
}
@Override
public Long countUnanswered(Project project) {
long questions = from(QActivityPlan.activityPlan)
.select(QChecklistQuestion.checklistQuestion.count())
.join(QActivityPlan.activityPlan.activities, QActivity.activity)
.join(QActivity.activity.checklist.questions, QChecklistQuestion.checklistQuestion)
.where(QActivityPlan.activityPlan.project.eq(project))
.fetchFirst();
.select(QChecklistQuestion.checklistQuestion.count())
.join(QActivityPlan.activityPlan.activities, QActivity.activity)
.join(QActivity.activity.checklist.questions, QChecklistQuestion.checklistQuestion)
.where(QActivityPlan.activityPlan.project.eq(project))
.fetchFirst();
questions = questions * project.getProjectParticipants().size();
long answers = from(QActivityPlan.activityPlan)
.select(QChecklistAnswer.checklistAnswer.count())
.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))
.fetchFirst();
.select(QChecklistAnswer.checklistAnswer.count())
.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))
.fetchFirst();
return questions - answers;
}
@ -64,4 +61,4 @@ public class ChecklistServiceImpl extends AbstractServiceImpl<Checklist, Long> i
checklist.getUserLastOpenDate().put(user, new Date());
return save(checklist);
}
}
}

@ -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",
joinColumns = @JoinColumn(name = "checklist_template_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "checklist_category_id", referencedColumnName = "id"))
@JoinTable(
name = "checklist_template_checklist_category",
joinColumns = @JoinColumn(name = "checklist_template_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "checklist_category_id", referencedColumnName = "id")
)
private List<ChecklistCategory> categories = new ArrayList<>();
@ManyToMany
@JoinTable(name = "checklist_template_project_type",
joinColumns = {@JoinColumn(name = "checklist_template_id")},
inverseJoinColumns = {@JoinColumn(name = "project_type_id")})
@JoinTable(
name = "checklist_template_project_type",
joinColumns = { @JoinColumn(name = "checklist_template_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;
@ -84,7 +85,7 @@ public class ChecklistTemplate extends DomainObject {
questions.add(question);
}
public void clearQuestions(){
public void clearQuestions() {
questions.clear();
}
@ -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) {
@ -171,4 +189,4 @@ public class ChecklistTemplate extends DomainObject {
public int hashCode() {
return Objects.hashCode(this.getId());
}
}
}

@ -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 {
@ -44,207 +43,176 @@ public class DaisyAPIImpl implements DaisyAPI {
@Inject
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.url") final String baseUrl,
@Named("daisy.api.username") final String user,
@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();
}
@Override
public Set<ProjectParticipant> getContributors(Integer projectId) {
return thesis()
.path(String.valueOf(projectId))
.path(CONTRIBUTOR)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.path(String.valueOf(projectId))
.path(CONTRIBUTOR)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
@Override
public Set<AuthorProjectParticipant> getAuthors(Integer projectId) {
return thesis()
.path(String.valueOf(projectId))
.path(AUTHOR)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.path(String.valueOf(projectId))
.path(AUTHOR)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
@Override
public Set<Thesis> getProjects(Integer personId) {
return person()
.path(String.valueOf(personId))
.path(THESES)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.path(String.valueOf(personId))
.path(THESES)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
@Override
public Set<Unit> getSubUnits(Integer unitId) {
return units()
.path(String.valueOf(unitId))
.path(SUBUNITS)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.path(String.valueOf(unitId))
.path(SUBUNITS)
.request(MediaType.APPLICATION_XML_TYPE)
.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<>() {
});
.path(String.valueOf(personId))
.path(USERNAMES)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
@Override
public List<ResearchArea> getResearchAreas(Integer personId) {
return person()
.path(String.valueOf(personId))
.path(RESEARCH_AREAS)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.path(String.valueOf(personId))
.path(RESEARCH_AREAS)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
@Override
public List<Person> getSupervisors(Integer unitId) {
return units()
.path(String.valueOf(unitId))
.path(SUPERVISORS)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.path(String.valueOf(unitId))
.path(SUPERVISORS)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
@Override
public Optional<Person> findPersonById(Integer id) {
Response response = person()
.path(String.valueOf(id))
.request(MediaType.APPLICATION_XML_TYPE)
.get(Response.class);
return response.getStatus() == 200
? Optional.of(response.readEntity(Person.class))
: Optional.empty();
.path(String.valueOf(id))
.request(MediaType.APPLICATION_XML_TYPE)
.get(Response.class);
return response.getStatus() == 200 ? Optional.of(response.readEntity(Person.class)) : Optional.empty();
}
@Override
public Optional<Person> findByUsername(String userName) {
Response response = person()
.path(USERNAME)
.path(userName)
.request(MediaType.APPLICATION_XML_TYPE)
.get(Response.class);
return response.getStatus() == 200
? Optional.of(response.readEntity(Person.class))
: Optional.empty();
.path(USERNAME)
.path(userName)
.request(MediaType.APPLICATION_XML_TYPE)
.get(Response.class);
return response.getStatus() == 200 ? Optional.of(response.readEntity(Person.class)) : Optional.empty();
}
@Override
public Response addContributor(Integer projectIdentifier, ProjectParticipant contributor) {
return thesis()
.path(String.valueOf(projectIdentifier))
.path(CONTRIBUTOR)
.request(MediaType.APPLICATION_XML_TYPE)
.post(xml(objectFactory.createProjectParticipant(contributor)));
.path(String.valueOf(projectIdentifier))
.path(CONTRIBUTOR)
.request(MediaType.APPLICATION_XML_TYPE)
.post(xml(objectFactory.createProjectParticipant(contributor)));
}
@Override
public Response deleteThesisPerson(Integer projectId, Integer personId) {
return thesis()
.path(String.valueOf(projectId))
.path(PERSON)
.path(String.valueOf(personId))
.request(MediaType.APPLICATION_XML_TYPE)
.delete();
.path(String.valueOf(projectId))
.path(PERSON)
.path(String.valueOf(personId))
.request(MediaType.APPLICATION_XML_TYPE)
.delete();
}
@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
public Response addAuthor(Integer projectId, AddThesisAuthor addThesisAuthor) {
return thesis()
.path(String.valueOf(projectId))
.path("author")
.request(MediaType.APPLICATION_XML_TYPE)
.post(xml(addThesisAuthor));
.path(String.valueOf(projectId))
.path("author")
.request(MediaType.APPLICATION_XML_TYPE)
.post(xml(addThesisAuthor));
}
@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
public Optional<Thesis> getThesis(Integer projectIdentifier) {
Response response = thesis()
.path(String.valueOf(projectIdentifier))
.request(MediaType.APPLICATION_XML_TYPE)
.get(Response.class);
return response.getStatus() == 200
? Optional.of(response.readEntity(Thesis.class))
: Optional.empty();
.path(String.valueOf(projectIdentifier))
.request(MediaType.APPLICATION_XML_TYPE)
.get(Response.class);
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
public Optional<String> getGradeForStudentInCourse(Long authorId, Integer courseId) {
Response response = course()
.path(String.valueOf(courseId))
.path(STUDENT)
.path(String.valueOf(authorId))
.request(MediaType.APPLICATION_XML_TYPE)
.get();
return response.getStatus() == 200
? Optional.ofNullable(response.readEntity(String.class))
: Optional.empty();
.path(String.valueOf(courseId))
.path(STUDENT)
.path(String.valueOf(authorId))
.request(MediaType.APPLICATION_XML_TYPE)
.get();
return response.getStatus() == 200 ? Optional.ofNullable(response.readEntity(String.class)) : Optional.empty();
}
@Override
public List<Person> findByPersonnummer(final String personnummer) {
return person()
.queryParam("personnummer", personnummer)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.queryParam("personnummer", personnummer)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
@Override
@ -252,12 +220,12 @@ public class DaisyAPIImpl implements DaisyAPI {
final Response response;
try {
response = person()
.path(String.valueOf(personId))
.path("photo")
.queryParam("show", alwaysShow)
.request()
.header("X-User-Id", requesterId)
.get();
.path(String.valueOf(personId))
.path("photo")
.queryParam("show", alwaysShow)
.request()
.header("X-User-Id", requesterId)
.get();
} catch (ProcessingException e) {
return new PhotoResult.Missing();
}
@ -279,10 +247,10 @@ public class DaisyAPIImpl implements DaisyAPI {
@Override
public Optional<ThesisPublication> getPublication(final long projectId) {
final Response response = thesis()
.path(Long.toString(projectId))
.path("publication")
.request(MediaType.APPLICATION_XML_TYPE)
.get();
.path(Long.toString(projectId))
.path("publication")
.request(MediaType.APPLICATION_XML_TYPE)
.get();
switch (response.getStatus()) {
case 200:
return Optional.of(response.readEntity(ThesisPublication.class));
@ -297,10 +265,10 @@ public class DaisyAPIImpl implements DaisyAPI {
@Override
public boolean sendPublication(final long projectId, final ThesisPublication publication) {
final Response response = thesis()
.path(Long.toString(projectId))
.path("publication")
.request(MediaType.APPLICATION_XML_TYPE)
.put(Entity.xml(publication));
.path(Long.toString(projectId))
.path("publication")
.request(MediaType.APPLICATION_XML_TYPE)
.put(Entity.xml(publication));
return response.getStatus() == 200;
}
@ -308,44 +276,42 @@ public class DaisyAPIImpl implements DaisyAPI {
public boolean sendPublicationFile(final long projectId, final String filename, final InputStream data) {
final String asciiOnlyFilename = asciify(filename);
final Response response = thesis()
.path(Long.toString(projectId))
.path("publication")
.path("file")
.request(MediaType.APPLICATION_XML_TYPE)
.header("X-Filename", asciiOnlyFilename)
.put(Entity.entity(data, "application/pdf"));
.path(Long.toString(projectId))
.path("publication")
.path("file")
.request(MediaType.APPLICATION_XML_TYPE)
.header("X-Filename", asciiOnlyFilename)
.put(Entity.entity(data, "application/pdf"));
return response.getStatus() == 200;
}
private static String asciify(String str) {
return str
.replace('Å', 'A')
.replace('Ä', 'A')
.replace('Ö', 'O')
.replace('å', 'a')
.replace('ä', 'a')
.replace('ö', 'o')
.replaceAll("\\P{ASCII}", ""); // Removes all remaining non-ASCII characters
.replace('Å', 'A')
.replace('Ä', 'A')
.replace('Ö', 'O')
.replace('å', 'a')
.replace('ä', 'a')
.replace('ö', 'o')
.replaceAll("\\P{ASCII}", ""); // Removes all remaining non-ASCII characters
}
@Override
public List<Program> getPrograms(final Integer responsibleDepartmentId) {
return program()
.queryParam("responsibleDepartment", responsibleDepartmentId)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.queryParam("responsibleDepartment", responsibleDepartmentId)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
@Override
public List<ProgramAdmission> getProgramAdmissions(final Program program, final Semester admissionSemester) {
return program()
.path(String.valueOf(program.getId()))
.path("admissions")
.queryParam("admissionSemester", admissionSemester.getId())
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.path(String.valueOf(program.getId()))
.path("admissions")
.queryParam("admissionSemester", admissionSemester.getId())
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
@Override
@ -353,23 +319,21 @@ public class DaisyAPIImpl implements DaisyAPI {
// have to pre-format the date parameter due to weird api handling of dates
final String sinceParameter = new SimpleDateFormat("yyyy-MM-dd").format(since);
return thesis()
.path("rejections")
.queryParam("since", sinceParameter)
// must be XML due to api date-formatting in json
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.path("rejections")
.queryParam("since", sinceParameter)
// must be XML due to api date-formatting in json
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
@Override
public List<StudentProgramAdmission> getProgramAdmissionsForStudent(final int studentId) {
try {
return student()
.path(Integer.toString(studentId))
.path("programAdmissions")
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.path(Integer.toString(studentId))
.path("programAdmissions")
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
} catch (NotFoundException ignored) {
return Collections.emptyList();
}
@ -379,11 +343,10 @@ public class DaisyAPIImpl implements DaisyAPI {
public List<CourseRegistration> getCourseRegistrationsForStudent(final int studentId) {
try {
return student()
.path(Integer.toString(studentId))
.path("courseRegistrations")
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {
});
.path(Integer.toString(studentId))
.path("courseRegistrations")
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
} catch (NotFoundException ignored) {
return Collections.emptyList();
}
@ -392,15 +355,16 @@ public class DaisyAPIImpl implements DaisyAPI {
@Override
public List<Employee> listEmployees(int departmentId) {
return target()
.path("employee")
.queryParam("department", departmentId)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
.path("employee")
.queryParam("department", departmentId)
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
@Override
public OrganisationalUnit orgunit(final int unitId) {
return () -> target()
return () ->
target()
.path("orgunit")
.path(Integer.toString(unitId))
.path("researchAreas")
@ -411,22 +375,22 @@ public class DaisyAPIImpl implements DaisyAPI {
@Override
public PublishingConsent getPublishingConsent(int projectId, int personId) {
return thesis()
.path(Integer.toString(projectId))
.path("author")
.path(Integer.toString(personId))
.path("publishingConsent")
.request(MediaType.APPLICATION_XML_TYPE)
.get(PublishingConsent.class);
.path(Integer.toString(projectId))
.path("author")
.path(Integer.toString(personId))
.path("publishingConsent")
.request(MediaType.APPLICATION_XML_TYPE)
.get(PublishingConsent.class);
}
@Override
public boolean setPublishingConsent(int projectId, int personId, PublishingConsentLevel publishingConsentLevel) {
final Invocation.Builder request = thesis()
.path(Integer.toString(projectId))
.path("author")
.path(Integer.toString(personId))
.path("publishingConsent")
.request(MediaType.APPLICATION_XML_TYPE);
.path(Integer.toString(projectId))
.path("author")
.path(Integer.toString(personId))
.path("publishingConsent")
.request(MediaType.APPLICATION_XML_TYPE);
// For some reason XML does not work
try (Response response = request.post(Entity.json(publishingConsentLevel))) {
@ -437,44 +401,37 @@ public class DaisyAPIImpl implements DaisyAPI {
@Override
public List<ResearchSubject> getNationalResearchSubjects(int organisationId) {
return units()
.path(Integer.toString(organisationId))
.path("nationalSubjectCategories")
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
.path(Integer.toString(organisationId))
.path("nationalSubjectCategories")
.request(MediaType.APPLICATION_XML_TYPE)
.get(new GenericType<>() {});
}
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,15 +1,15 @@
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;
public enum Type {
public enum Type {
AUTHOR {
@Override
public String toString() {
@ -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;

@ -1,27 +1,25 @@
package se.su.dsv.scipro.data.enums;
public enum MailChoice {
THESIS_SUPPORT("Thesis support"),
AUTHORS_ACTIVE_PROJECT("Authors with active projects"),
ACTIVE_SUPERVISORS("Head supervisors with active projects"),
ACTIVE_CO_SUPERVISORS("Co-supervisors with active projects"),
ACTIVE_REVIEWERS("Reviewers of active projects"),
ALL_FOLLOWERS("All supervisors and reviewers of active projects"),
AUTHORS_SUBMITTED_IDEA("Authors with submitted ideas"),
AUTHORS_MATCHED_IDEA("Authors with matched ideas"),
SUPERVISORS_MATCHED_IDEA("Supervisors with matched ideas"),
SUPERVISORS_SUBMITTED_IDEA("Supervisors with submitted ideas");
private String asString;
THESIS_SUPPORT("Thesis support"),
AUTHORS_ACTIVE_PROJECT("Authors with active projects"),
ACTIVE_SUPERVISORS("Head supervisors with active projects"),
ACTIVE_CO_SUPERVISORS("Co-supervisors with active projects"),
ACTIVE_REVIEWERS("Reviewers of active projects"),
ALL_FOLLOWERS("All supervisors and reviewers of active projects"),
AUTHORS_SUBMITTED_IDEA("Authors with submitted ideas"),
AUTHORS_MATCHED_IDEA("Authors with matched ideas"),
SUPERVISORS_MATCHED_IDEA("Supervisors with matched ideas"),
SUPERVISORS_SUBMITTED_IDEA("Supervisors with submitted ideas");
private String asString;
MailChoice(String asString) {
this.asString = asString;
}
@Override
public String toString() {
return asString;
}
@Override
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)));
@ -91,7 +102,7 @@ public class MailFacade implements Serializable {
List<Project> listOfProjects = projectService.findAll(filter);
Set<Recipient> recipients = new HashSet<>();
for (Project p : listOfProjects) {
for (User user : p.getCoSupervisors()){
for (User user : p.getCoSupervisors()) {
recipients.add(new UserRecipient(user));
}
}
@ -103,7 +114,7 @@ public class MailFacade implements Serializable {
List<Project> listOProjects = projectService.findAll(filter);
Set<Recipient> recipients = new HashSet<>();
for (Project p : listOProjects) {
for (User user : p.getReviewers()){
for (User user : p.getReviewers()) {
recipients.add(new UserRecipient(user));
}
}
@ -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,10 +1,9 @@
package se.su.dsv.scipro.date;
import java.util.Date;
import se.su.dsv.scipro.data.enums.DateStyle;
import java.util.Date;
public interface DateService {
public interface DateService {
String format(Date date);
String format(Date date, DateStyle style);
String getFormat(DateStyle style);

@ -1,15 +1,12 @@
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){
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 {
@ -30,8 +29,8 @@ public class FileReferenceRepositoryImpl extends AbstractRepository implements F
@Override
public long countReferencesTo(final FileDescription fileDescription) {
return from(QFileReference.fileReference)
.select(QFileReference.fileReference.count())
.where(QFileReference.fileReference.fileDescription.eq(fileDescription))
.fetchOne();
.select(QFileReference.fileReference.count())
.where(QFileReference.fileReference.fileDescription.eq(fileDescription))
.fetchOne();
}
}

@ -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 {
@ -16,11 +15,11 @@ public class FileServiceImpl extends AbstractServiceImpl<FileDescription, Long>
@Inject
public FileServiceImpl(
Provider<EntityManager> em,
final FileReferenceRepository fileReferenceRepository,
final FileDescriptionRepo fileDescriptionRepository,
final FileStore fileStore)
{
Provider<EntityManager> em,
final FileReferenceRepository fileReferenceRepository,
final FileDescriptionRepo fileDescriptionRepository,
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);
}
}
}

@ -1,11 +1,11 @@
package se.su.dsv.scipro.file;
public enum FileSource {
public enum FileSource {
FILES,
FORUM,
FINAL_THESIS,
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);
@ -20,10 +20,10 @@ public class ProjectFileRepositoryImpl extends AbstractServiceImpl<ProjectFile,
@Override
public List<ProjectFile> latestUpload(final Project project, final int amount) {
return new JPAQuery<ProjectFile>(em())
.from(QProjectFile.projectFile)
.where(QProjectFile.projectFile.project.eq(project))
.limit(amount)
.fetch();
.from(QProjectFile.projectFile)
.where(QProjectFile.projectFile.project.eq(project))
.limit(amount)
.fetch();
}
@Override
@ -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(
QProjectFile.projectFile.fileReference.fileDescription.eq(fileDescription),
QProjectFile.projectFile.project.eq(project))));
return Optional.ofNullable(
findOne(
Expressions.allOf(
QProjectFile.projectFile.fileReference.fileDescription.eq(fileDescription),
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<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
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<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
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<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
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<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
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<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
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<TooManyParticipants, A> a,
Function<ManualParticipants, A> b,
Function<ParticipationAlreadyParticipating, A> e,
Function<ParticipationAlreadyHappened, A> f,
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(),
author.project.projectType.eq(projectType),
author.project.projectStatus.eq(ProjectStatus.ACTIVE))
.fetch();
.where(
author.subscribedToFinalSeminarNotifications.isTrue(),
author.project.projectType.eq(projectType),
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;
@ -100,7 +99,7 @@ public class FinalSeminar extends LazyDeletableDomainObject {
@OneToOne(optional = false)
@JoinColumn(name = "project_id", referencedColumnName = "id")
@QueryInit({"projectType", "headSupervisor"})
@QueryInit({ "projectType", "headSupervisor" })
private Project project;
// ----------------------------------------------------------------------------------
@ -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() +
")"
);
}
// ----------------------------------------------------------------------------------
@ -314,9 +331,9 @@ public class FinalSeminar extends LazyDeletableDomainObject {
activeParticipations.removeIf(next -> next.getUser().equals(user));
}
public Set<User> getActiveParticipants(){
public Set<User> getActiveParticipants() {
Set<User> activeParticipants = new HashSet<>();
for (FinalSeminarActiveParticipation fsap : activeParticipations){
for (FinalSeminarActiveParticipation fsap : activeParticipations) {
activeParticipants.add(fsap.getUser());
}
return activeParticipants;
@ -334,9 +351,9 @@ public class FinalSeminar extends LazyDeletableDomainObject {
this.oppositions.remove(opposition);
}
public Set<User> getOpponents(){
public Set<User> getOpponents() {
Set<User> opponents = new HashSet<>();
for (FinalSeminarOpposition fso : oppositions){
for (FinalSeminarOpposition fso : oppositions) {
opponents.add(fso.getUser());
}
return opponents;
@ -353,7 +370,7 @@ public class FinalSeminar extends LazyDeletableDomainObject {
private Collection<User> getNotGradedParticipations(Set<? extends FinalSeminarParticipation> participations) {
List<User> result = new ArrayList<>();
for (FinalSeminarParticipation participation : participations) {
if(participation.getGrade() == null) {
if (participation.getGrade() == null) {
result.add(participation.getUser());
}
}

@ -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);
@ -18,8 +20,8 @@ public class FinalSeminarActiveParticipationRepositoryImpl extends AbstractRepos
@Override
public List<FinalSeminarActiveParticipation> findByParticipatingUserAndLevel(User user, ProjectType projectType) {
return from(QFinalSeminarActiveParticipation.finalSeminarActiveParticipation)
.where(QFinalSeminarActiveParticipation.finalSeminarActiveParticipation.user.eq(user))
.where(QFinalSeminarActiveParticipation.finalSeminarActiveParticipation.project.projectType.eq(projectType))
.fetch();
.where(QFinalSeminarActiveParticipation.finalSeminarActiveParticipation.user.eq(user))
.where(QFinalSeminarActiveParticipation.finalSeminarActiveParticipation.project.projectType.eq(projectType))
.fetch();
}
}

@ -3,7 +3,6 @@ package se.su.dsv.scipro.finalseminar;
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);
public interface FinalSeminarActiveParticipationService extends GenericService<FinalSeminarActiveParticipation, Long> {
FinalSeminarActiveParticipation findByFinalSeminarUser(FinalSeminar finalSeminar, User user);
}

@ -1,28 +1,31 @@
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){
public FinalSeminarActiveParticipation findByFinalSeminarUser(FinalSeminar finalSeminar, User user) {
for (FinalSeminarActiveParticipation fsap : finalSeminar.getActiveParticipations()) {
if(fsap.getUser().equals(user)){
if (fsap.getUser().equals(user)) {
return fsap;
}
}
return null;
return null;
}
}

@ -3,17 +3,18 @@ package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.project.Project;
public final class FinalSeminarCreatedEvent {
private final FinalSeminar finalSeminar;
public FinalSeminar getFinalSeminar(){
private final FinalSeminar finalSeminar;
public FinalSeminar getFinalSeminar() {
return finalSeminar;
}
public FinalSeminarCreatedEvent(FinalSeminar finalSeminar) {
this.finalSeminar = finalSeminar;
}
public FinalSeminarCreatedEvent(FinalSeminar finalSeminar) {
this.finalSeminar = finalSeminar;
}
public Project getProject() {
return finalSeminar.getProject();
}
public Project getProject() {
return finalSeminar.getProject();
}
}

@ -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,21 +13,17 @@ 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;
FinalSeminarCreationSubscribers(
AuthorRepository authorRepository,
FinalSeminarService finalSeminarService,
NotificationController notificationController)
{
AuthorRepository authorRepository,
FinalSeminarService finalSeminarService,
NotificationController notificationController
) {
this.authorRepository = authorRepository;
this.finalSeminarService = finalSeminarService;
this.notificationController = notificationController;
@ -31,42 +31,54 @@ public class FinalSeminarCreationSubscribers {
@Inject
public FinalSeminarCreationSubscribers(
AuthorRepository authorRepository,
FinalSeminarService finalSeminarService,
NotificationController notificationController,
EventBus eventBus)
{
AuthorRepository authorRepository,
FinalSeminarService finalSeminarService,
NotificationController notificationController,
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);
.stream()
.map(user -> new Member(user, Member.Type.OPPONENT))
.collect(Collectors.toSet());
notificationController.notifyCustomSeminar(
event.getFinalSeminar(),
SeminarEvent.Event.CREATED,
new NotificationSource(),
users
);
}
private List<User> getSubscribersStillNeedingOppositionOrParticipation(List<Author> subscribers) {
return subscribers
.stream()
.filter(subscriber -> onlyFailedOppositions(subscriber) || onlyFailedParticipations(subscriber))
.map(Author::getUser)
.toList();
.stream()
.filter(subscriber -> onlyFailedOppositions(subscriber) || onlyFailedParticipations(subscriber))
.map(Author::getUser)
.toList();
}
private boolean onlyFailedParticipations(Author subscriber) {
return finalSeminarService.findUserParticipating(subscriber.getProject(), subscriber.getUser())
.stream()
.noneMatch(FinalSeminarParticipation::isApproved);
return finalSeminarService
.findUserParticipating(subscriber.getProject(), subscriber.getUser())
.stream()
.noneMatch(FinalSeminarParticipation::isApproved);
}
private boolean onlyFailedOppositions(Author subscriber) {
return finalSeminarService.findFinalSeminarOppositionsByOpponentAndProjectType(subscriber.getProject().getProjectType(), subscriber.getUser())
.stream()
.noneMatch(FinalSeminarParticipation::isApproved);
return finalSeminarService
.findFinalSeminarOppositionsByOpponentAndProjectType(
subscriber.getProject().getProjectType(),
subscriber.getUser()
)
.stream()
.noneMatch(FinalSeminarParticipation::isApproved);
}
}

@ -3,17 +3,18 @@ package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.project.Project;
public final class FinalSeminarDeletedEvent {
private final FinalSeminar finalSeminar;
public FinalSeminar getFinalSeminar(){
private final FinalSeminar finalSeminar;
public FinalSeminar getFinalSeminar() {
return finalSeminar;
}
public FinalSeminarDeletedEvent(FinalSeminar finalSeminar) {
this.finalSeminar = finalSeminar;
}
public FinalSeminarDeletedEvent(FinalSeminar finalSeminar) {
this.finalSeminar = finalSeminar;
}
public Project getProject() {
return finalSeminar.getProject();
}
public Project getProject() {
return finalSeminar.getProject();
}
}

@ -3,12 +3,11 @@ package se.su.dsv.scipro.finalseminar;
import se.su.dsv.scipro.system.Language;
public record FinalSeminarDetails(
String location,
Boolean manualParticipants,
int maxParticipants,
int maxOpponents,
Language presentationLanguage,
Language reportLanguage,
String extraInfo)
{
}
String location,
Boolean manualParticipants,
int maxParticipants,
int maxOpponents,
Language presentationLanguage,
Language reportLanguage,
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")
@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);
@ -18,8 +20,8 @@ public class FinalSeminarOppositionRepoImpl extends GenericRepo<FinalSeminarOppo
@Override
public List<FinalSeminarOpposition> findByOpposingUserAndType(User user, ProjectType projectType) {
return createQuery()
.where(QFinalSeminarOpposition.finalSeminarOpposition.user.eq(user))
.where(QFinalSeminarOpposition.finalSeminarOpposition.project.projectType.eq(projectType))
.fetch();
.where(QFinalSeminarOpposition.finalSeminarOpposition.user.eq(user))
.where(QFinalSeminarOpposition.finalSeminarOpposition.project.projectType.eq(projectType))
.fetch();
}
}

@ -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);
@ -36,7 +40,7 @@ public class FinalSeminarRespondentServiceImpl extends AbstractServiceImpl<Final
@Override
@Transactional
public List<FinalSeminarRespondent> findOrCreate(FinalSeminar finalSeminar) {
if(finalSeminar.getId() == null) {
if (finalSeminar.getId() == null) {
return new ArrayList<>();
}
List<FinalSeminarRespondent> finalSeminarRespondents = new ArrayList<>();

@ -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) {
@ -166,29 +193,42 @@ public interface FinalSeminarService extends GenericService<FinalSeminar, Long>,
@Override
public int hashCode() {
return Objects.hash(
this.getFromDate(),
this.getToDate(),
this.getLazyDeleted(),
this.getExempted(),
this.getOnlyActiveProjects(),
this.getOnlyActiveOrCompletedProjects(),
this.getHeadSupervisor(),
this.getDegreeType(),
this.getOnlyNonManualParticipants());
this.getFromDate(),
this.getToDate(),
this.getLazyDeleted(),
this.getExempted(),
this.getOnlyActiveProjects(),
this.getOnlyActiveOrCompletedProjects(),
this.getHeadSupervisor(),
this.getDegreeType(),
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;
@ -50,15 +52,16 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
@Inject
public FinalSeminarServiceImpl(
Provider<EntityManager> em,
EventBus eventBus,
AuthorRepository authorRepository,
final FileService fileService,
FinalSeminarOppositionRepo finalSeminarOppositionRepository,
FinalSeminarActiveParticipationRepository finalSeminarActiveParticipationRepository,
FinalSeminarRepository finalSeminarRepository,
Clock clock,
RoughDraftApprovalService roughDraftApprovalService) {
Provider<EntityManager> em,
EventBus eventBus,
AuthorRepository authorRepository,
final FileService fileService,
FinalSeminarOppositionRepo finalSeminarOppositionRepository,
FinalSeminarActiveParticipationRepository finalSeminarActiveParticipationRepository,
FinalSeminarRepository finalSeminarRepository,
Clock clock,
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,9 +87,10 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
SchedulingError violation = validateSchedulingRules(when.toLocalDate());
if (violation != null) return Either.left(violation);
boolean roughDraftApproved = roughDraftApprovalService.findBy(project)
.map(RoughDraftApproval::isApproved)
.orElse(Boolean.FALSE);
boolean roughDraftApproved = roughDraftApprovalService
.findBy(project)
.map(RoughDraftApproval::isApproved)
.orElse(Boolean.FALSE);
if (!roughDraftApproved) {
return Either.left(new RoughDraftNotApproved());
}
@ -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);
}
@ -116,9 +123,10 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
}
private Either<SchedulingError, FinalSeminar> createSeminar(
Project project,
LocalDateTime when,
FinalSeminarDetails details) {
Project project,
LocalDateTime when,
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,17 +475,18 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
@Override
public List<FinalSeminarOpposition> getOppositionsByProjectAuthors(Project project) {
return project.getProjectParticipants()
.stream()
.map(author -> findFinalSeminarOppositionsByOpponentAndProjectType(project.getProjectType(), author))
.flatMap(List::stream)
.toList();
return project
.getProjectParticipants()
.stream()
.map(author -> findFinalSeminarOppositionsByOpponentAndProjectType(project.getProjectType(), author))
.flatMap(List::stream)
.toList();
}
@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(),
seminar.activeParticipations.any().grade.isNull(),
seminar.respondents.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()
);
}
}

@ -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) {
@ -143,13 +162,14 @@ public class FinalSeminarSettings extends DomainObject {
@Override
public int hashCode() {
return Objects.hash(
this.getId(),
this.getDaysAheadToCreate(),
this.getDaysAheadToRegisterParticipation(),
this.getDaysAheadToRegisterOpposition(),
this.getDaysAheadToUploadThesis(),
this.isThesisMustBePDF(),
this.getEvaluationURL(),
this.getOppositionPriorityDays());
this.getId(),
this.getDaysAheadToCreate(),
this.getDaysAheadToRegisterParticipation(),
this.getDaysAheadToRegisterOpposition(),
this.getDaysAheadToUploadThesis(),
this.isThesisMustBePDF(),
this.getEvaluationURL(),
this.getOppositionPriorityDays()
);
}
}

@ -1,29 +1,30 @@
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;
private static final long INSTANCE_ID = 1L;
@Inject
public FinalSeminarSettingsServiceImpl(Provider<EntityManager> em) {
@Inject
public FinalSeminarSettingsServiceImpl(Provider<EntityManager> em) {
super(em, FinalSeminarSettings.class, QFinalSeminarSettings.finalSeminarSettings);
}
}
@Override
@Transactional
public FinalSeminarSettings getInstance() {
FinalSeminarSettings settings = findOne(INSTANCE_ID);
if(settings==null) {
settings = new FinalSeminarSettings(INSTANCE_ID);
save(settings);
}
return settings;
}
@Override
@Transactional
public FinalSeminarSettings getInstance() {
FinalSeminarSettings settings = findOne(INSTANCE_ID);
if (settings == null) {
settings = new FinalSeminarSettings(INSTANCE_ID);
save(settings);
}
return settings;
}
}

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

@ -3,11 +3,12 @@ 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) {
this.seminar = seminar;
}
}
public FinalSeminar getFinalSeminar() {
return seminar;

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