Merge commit 'ff4c5b58b40db5fcb7754c259c3854194668c1e1' into HEAD

This commit is contained in:
Jenkins 2024-11-21 19:54:07 +01:00
commit b52e28297c
336 changed files with 12448 additions and 4923 deletions
.gitignoreGetToken.javaREADME.md
api
pom.xml
src/main/java/se/su/dsv/scipro/api
core
pom.xml
src/main/java
modules
se/su/dsv/scipro
CoreConfig.javaDataInitializer.javaRepositoryConfiguration.java
activityplan
checklist
daisyExternal
events
file
finalseminar
finalthesis
firstmeeting
forum
gdpr
generalsystemsettings
grading
group
integration
mail
match

2
.gitignore vendored

@ -23,3 +23,5 @@ view/target
*.log
fitnesse/target/
daisy-integration/target/
war/target/
api/target/

101
GetToken.java Normal file

@ -0,0 +1,101 @@
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpServer;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class GetToken {
public static void main(String[] args) throws IOException {
URI baseUri = URI.create("http://localhost:59733");
String clientId = "get-token";
String clientSecret = "get-token-secret";
System.out.println("Browse to " + baseUri.resolve("authorize?response_type=code&client_id=" + clientId));
HttpClient httpClient = HttpClient.newBuilder()
.authenticator(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(clientId, clientSecret.toCharArray());
}
})
.build();
HttpServer httpServer = HttpServer.create();
httpServer.bind(new InetSocketAddress(59732), 0);
Thread thread = Thread.currentThread();
httpServer.createContext("/", exchange -> {
exchange.sendResponseHeaders(200, 0);
try (OutputStream responseBody = exchange.getResponseBody()) {
responseBody.write("All done, close tab".getBytes(StandardCharsets.UTF_8));
}
Map<String, List<String>> queryParams = getQueryParams(exchange);
String code = queryParams.get("code").get(0);
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(baseUri.resolve("exchange"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString("grant_type=authorization_code&code=" + code))
.build();
try {
HttpResponse<String> response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
// Try to copy the access token to the clipboard
Matcher matcher = Pattern.compile("access_token\":\"([^\"]+)\"")
.matcher(response.body());
if (matcher.find()) {
StringSelection clipboardData = new StringSelection(matcher.group(1));
Toolkit.getDefaultToolkit()
.getSystemClipboard()
.setContents(clipboardData, clipboardData);
try { Thread.sleep(1_000L); } catch (InterruptedException e) { }
System.out.println("Access token copied to clipboard (probably)");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
thread.interrupt();
}
});
httpServer.start();
try {
Thread.sleep(Duration.ofMinutes(1L).toMillis());
System.out.println("No authorization within one minute, exiting.");
System.exit(1);
} catch (InterruptedException ignored) {
// expected
}
httpServer.stop(0);
}
private static Map<String, List<String>> getQueryParams(final HttpExchange exchange) {
String query = exchange.getRequestURI()
.getQuery();
return Arrays.stream(query.split("&"))
.map(s -> s.split("="))
.collect(Collectors.groupingBy(
split -> split[0],
Collectors.mapping(split -> split[1], Collectors.toList())));
}
}

13
README.md Normal file

@ -0,0 +1,13 @@
## Working with the API
The API is protected by OAuth 2 acting as a [resource server](https://www.oauth.com/oauth2-servers/the-resource-server/)
verifying tokens using [token introspection](https://datatracker.ietf.org/doc/html/rfc7662).
When developing it uses a locally running instance of an
[authorization server](https://datatracker.ietf.org/doc/html/rfc6749#section-1.1)
that is run inside [Docker](https://www.docker.com). It can be started with `docker compose -f docker-compose.yml up`.
Since there is no frontend to interact with the authorization server there's a helper script in
[GetToken.java](GetToken.java) that can be run directly with `java GetToken.java` to run through the authorization flow
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.

25
api/pom.xml Normal file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>se.su.dsv.scipro</groupId>
<artifactId>SciPro</artifactId>
<version>0.1-SNAPSHOT</version>
</parent>
<artifactId>api</artifactId>
<dependencies>
<dependency>
<groupId>se.su.dsv.scipro</groupId>
<artifactId>core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,29 @@
package se.su.dsv.scipro.api;
import jakarta.inject.Inject;
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
public ApiController(UserService userService) {
this.userService = userService;
}
@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");
return "Hello, " + name + "!";
}
}

@ -12,14 +12,6 @@
<artifactId>core</artifactId>
<dependencies>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-persist</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
@ -62,12 +54,9 @@
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
</dependency>
<!--Database stuff-->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<!--QueryDSL-->
@ -87,10 +76,19 @@
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.transaction</groupId>
<artifactId>jakarta.transaction-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<scope>runtime</scope>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<!--Additional stuff-->
@ -130,8 +128,6 @@
<version>4.0.5</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>

@ -1,160 +0,0 @@
package modules;
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.multibindings.OptionalBinder;
import se.su.dsv.scipro.activityplan.*;
import se.su.dsv.scipro.checklist.*;
import se.su.dsv.scipro.date.DateService;
import se.su.dsv.scipro.date.DateServiceImpl;
import se.su.dsv.scipro.events.EventModule;
import se.su.dsv.scipro.finalseminar.*;
import se.su.dsv.scipro.finalthesis.FinalThesisService;
import se.su.dsv.scipro.finalthesis.FinalThesisServiceImpl;
import se.su.dsv.scipro.finalthesis.PublishingConsentService;
import se.su.dsv.scipro.finalthesis.PublishingConsentUnavailable;
import se.su.dsv.scipro.firstmeeting.FirstMeetingService;
import se.su.dsv.scipro.firstmeeting.FirstMeetingServiceImpl;
import se.su.dsv.scipro.forum.ForumModule;
import se.su.dsv.scipro.generalsystemsettings.GeneralSystemSettingsService;
import se.su.dsv.scipro.generalsystemsettings.GeneralSystemSettingsServiceImpl;
import se.su.dsv.scipro.group.GroupFacade;
import se.su.dsv.scipro.group.GroupFacadeImpl;
import se.su.dsv.scipro.group.GroupService;
import se.su.dsv.scipro.group.GroupServiceImpl;
import se.su.dsv.scipro.integration.activityfinalseminar.ActivityFinalSeminarRepository;
import se.su.dsv.scipro.integration.activityfinalseminar.ActivityFinalSeminarRepositoryImpl;
import se.su.dsv.scipro.integration.activityforum.ActivityThreadRepository;
import se.su.dsv.scipro.integration.activityforum.ActivityThreadRepositoryImpl;
import se.su.dsv.scipro.mail.MailModule;
import se.su.dsv.scipro.match.ApplicationPeriodFacade;
import se.su.dsv.scipro.match.ApplicationPeriodFacadeImpl;
import se.su.dsv.scipro.match.MatchModule;
import se.su.dsv.scipro.milestones.service.*;
import se.su.dsv.scipro.milestones.service.impl.MilestoneActivityTemplateServiceImpl;
import se.su.dsv.scipro.milestones.service.impl.MilestonePhaseTemplateServiceImpl;
import se.su.dsv.scipro.milestones.service.impl.MilestoneServiceImpl;
import se.su.dsv.scipro.milestones.service.impl.MilestoneStatisticsServiceImpl;
import se.su.dsv.scipro.misc.DaysService;
import se.su.dsv.scipro.misc.DaysServiceImpl;
import se.su.dsv.scipro.nonworkperiod.NonWorkDayPeriodService;
import se.su.dsv.scipro.nonworkperiod.NonWorkDayPeriodServiceImpl;
import se.su.dsv.scipro.notes.NoteService;
import se.su.dsv.scipro.notes.NoteServiceImpl;
import se.su.dsv.scipro.notifications.NotificationModule;
import se.su.dsv.scipro.notifications.settings.service.DeliveryConfigurationService;
import se.su.dsv.scipro.notifications.settings.service.DeliveryConfigurationServiceImpl;
import se.su.dsv.scipro.notifications.settings.service.ReceiverConfigurationService;
import se.su.dsv.scipro.notifications.settings.service.ReceiverConfigurationServiceImpl;
import se.su.dsv.scipro.peer.*;
import se.su.dsv.scipro.plagiarism.*;
import se.su.dsv.scipro.project.ProjectNoteService;
import se.su.dsv.scipro.project.ProjectPeopleStatisticsService;
import se.su.dsv.scipro.project.ProjectPeopleStatisticsServiceImpl;
import se.su.dsv.scipro.project.ProjectService;
import se.su.dsv.scipro.project.ProjectServiceImpl;
import se.su.dsv.scipro.projectpartner.ProjectPartnerRepository;
import se.su.dsv.scipro.projectpartner.ProjectPartnerRepositoryImpl;
import se.su.dsv.scipro.projectpartner.ProjectPartnerService;
import se.su.dsv.scipro.projectpartner.ProjectPartnerServiceImpl;
import se.su.dsv.scipro.reflection.ReflectionModule;
import se.su.dsv.scipro.report.*;
import se.su.dsv.scipro.reviewing.ProjectFinalSeminarStatisticsService;
import se.su.dsv.scipro.reviewing.ProjectFinalSeminarStatisticsServiceImpl;
import se.su.dsv.scipro.springdata.serviceimpls.SupervisorServiceImpl;
import se.su.dsv.scipro.springdata.serviceimpls.UnitServiceImpl;
import se.su.dsv.scipro.springdata.serviceimpls.UserProfileServiceImpl;
import se.su.dsv.scipro.springdata.services.SupervisorService;
import se.su.dsv.scipro.springdata.services.UnitService;
import se.su.dsv.scipro.springdata.services.UserProfileService;
import se.su.dsv.scipro.system.*;
import se.su.dsv.scipro.thesislink.ExternalLinkService;
import se.su.dsv.scipro.thesislink.ExternalLinkServiceImpl;
public class CoreModule extends AbstractModule {
@Override
protected void configure() {
install(new RepositoryModule());
bind(FooterLinkService.class).to(FooterLinkServiceImpl.class);
bind(ActivityThreadRepository.class).to(ActivityThreadRepositoryImpl.class);
bind(ActivityFinalSeminarRepository.class).to(ActivityFinalSeminarRepositoryImpl.class);
bind(UserService.class).to(UserServiceImpl.class);
bind(MergeService.class).to(MergeServiceImpl.class);
bind(PasswordService.class).to(PasswordServiceImpl.class);
bind(GeneralSystemSettingsService.class).to(GeneralSystemSettingsServiceImpl.class);
bind(ProjectTypeService.class).to(ProjectTypeServiceImpl.class);
bind(UnitService.class).to(UnitServiceImpl.class);
bind(ResearchAreaService.class).to(ResearchAreaServiceImpl.class);
bind(DateService.class).to(DateServiceImpl.class);
bind(ActivityPlanFacade.class).to(ActivityPlanFacadeImpl.class);
bind(ProjectService.class).to(ProjectServiceImpl.class);
bind(ProjectFinalSeminarStatisticsService.class).to(ProjectFinalSeminarStatisticsServiceImpl.class);
bind(ProjectPeopleStatisticsService.class).to(ProjectPeopleStatisticsServiceImpl.class);
bind(DeliveryConfigurationService.class).to(DeliveryConfigurationServiceImpl.class);
bind(ReceiverConfigurationService.class).to(ReceiverConfigurationServiceImpl.class);
bind(ActivityService.class).to(ActivityServiceImpl.class);
bind(ActivityPlanService.class).to(ActivityPlanServiceImpl.class);
bind(ActivityPlanTemplateService.class).to(ActivityPlanTemplateServiceImpl.class);
bind(ChecklistService.class).to(ChecklistServiceImpl.class);
bind(UserProfileService.class).to(UserProfileServiceImpl.class);
bind(FinalSeminarService.class).to(FinalSeminarServiceImpl.class);
bind(FinalSeminarSettingsService.class).to(FinalSeminarSettingsServiceImpl.class);
bind(SupervisorService.class).to(SupervisorServiceImpl.class);
bind(DaysService.class).to(DaysServiceImpl.class);
bind(NonWorkDayPeriodService.class).to(NonWorkDayPeriodServiceImpl.class);
bind(FinalSeminarOppositionService.class).to(FinalSeminarOppositionServiceImpl.class);
bind(AuthorRepository.class).to(AuthorRepositoryImpl.class);
bind(OppositionReportService.class).to(OppositionReportServiceImpl.class);
bind(ApplicationPeriodFacade.class).to(ApplicationPeriodFacadeImpl.class);
bind(GroupFacade.class).to(GroupFacadeImpl.class);
bind(ExternalLinkService.class).to(ExternalLinkServiceImpl.class);
bind(PeerRequestService.class).to(PeerRequestServiceImpl.class);
bind(PeerReviewService.class).to(PeerReviewServiceImpl.class);
bind(MilestoneActivityTemplateService.class).to(MilestoneActivityTemplateServiceImpl.class);
bind(FinalThesisService.class).to(FinalThesisServiceImpl.class);
OptionalBinder.newOptionalBinder(binder(), PublishingConsentService.class)
.setDefault().to(PublishingConsentUnavailable.class);
bind(ChecklistTemplateService.class).to(ChecklistTemplateServiceImpl.class);
bind(PeerPortal.class).to(PeerPortalImpl.class);
bind(FinalSeminarRespondentService.class).to(FinalSeminarRespondentServiceImpl.class);
bind(ProjectPartnerService.class).to(ProjectPartnerServiceImpl.class);
bind(GradingReportService.class).to(GradingReportServiceImpl.class);
bind(GradeCalculatorService.class).to(GradeCalculatorServiceImpl.class);
bind(UserNameService.class).to(UserNameServiceImpl.class);
bind(MileStoneService.class).to(MilestoneServiceImpl.class);
bind(MilestoneStatisticsService.class).to(MilestoneStatisticsServiceImpl.class);
bind(MilestonePhaseTemplateService.class).to(MilestonePhaseTemplateServiceImpl.class);
bind(ReportService.class).to(ReportServiceImpl.class);
bind(CommentThreadService.class).to(CommentThreadServiceImpl.class);
bind(CommentService.class).to(CommentServiceImpl.class);
bind(PerformReviewService.class).to(PeerPortalImpl.class);
bind(EventService.class).to(EventServiceImpl.class);
bind(ChecklistAnswerService.class).to(ChecklistAnswerServiceImpl.class);
bind(FinalSeminarUploadController.class).to(FinalSeminarUploadControllerImpl.class);
bind(FinalSeminarActiveParticipationService.class).to(FinalSeminarActiveParticipationServiceImpl.class);
bind(ExternalResourceService.class).to(ExternalResourceServiceImpl.class);
bind(GroupService.class).to(GroupServiceImpl.class);
bind(NoteService.class).to(NoteServiceImpl.class);
bind(MilestoneActivator.class).asEagerSingleton();
bind(ActivateCompletedMilestonesOnNewProjects.class).asEagerSingleton();
bind(FirstMeetingService.class).to(FirstMeetingServiceImpl.class);
bind(FinalSeminarCreationSubscribers.class).asEagerSingleton();
bind(ProjectPartnerRepository.class).to(ProjectPartnerRepositoryImpl.class);
bind(ProjectNoteService.class).to(ProjectServiceImpl.class);
install(new PlagiarismModule());
install(new NotificationModule());
install(new ProfileModule());
install(new EventModule());
install(new MatchModule());
install(new MailModule());
install(new ForumModule());
install(new ReflectionModule());
Multibinder.newSetBinder(binder(), UserImportService.class);
bind(UserSearchService.class).to(AggregateUserSearch.class);
Multibinder.newSetBinder(binder(), UserSearchProvider.class)
.addBinding().to(LocalUserSearch.class);
}
}

@ -1,15 +0,0 @@
package modules;
import com.google.inject.Key;
import com.google.inject.PrivateModule;
import com.google.inject.name.Names;
import se.su.dsv.scipro.profiles.CurrentProfile;
public class ProfileModule extends PrivateModule {
@Override
protected void configure() {
requireBinding(Key.get(String.class, Names.named("profile")));
bind(CurrentProfile.class).asEagerSingleton();
expose(CurrentProfile.class);
}
}

@ -1,66 +0,0 @@
package modules;
import com.google.inject.AbstractModule;
import se.su.dsv.scipro.checklist.ChecklistCategoryRepo;
import se.su.dsv.scipro.checklist.ChecklistCategoryRepoImpl;
import se.su.dsv.scipro.checklist.ChecklistQuestionRepo;
import se.su.dsv.scipro.checklist.ChecklistQuestionRepoImpl;
import se.su.dsv.scipro.finalseminar.FinalSeminarActiveParticipationRepository;
import se.su.dsv.scipro.finalseminar.FinalSeminarActiveParticipationRepositoryImpl;
import se.su.dsv.scipro.finalseminar.FinalSeminarOppositionRepo;
import se.su.dsv.scipro.finalseminar.FinalSeminarOppositionRepoImpl;
import se.su.dsv.scipro.finalseminar.FinalSeminarRepository;
import se.su.dsv.scipro.finalseminar.FinalSeminarRepositoryImpl;
import se.su.dsv.scipro.milestones.MilestoneActivityTemplateRepository;
import se.su.dsv.scipro.milestones.MilestoneActivityTemplateRepositoryImpl;
import se.su.dsv.scipro.peer.CommentThreadRepo;
import se.su.dsv.scipro.peer.CommentThreadRepoImpl;
import se.su.dsv.scipro.peer.PeerRequestRepository;
import se.su.dsv.scipro.peer.PeerRequestRepositoryImpl;
import se.su.dsv.scipro.peer.PeerReviewRepository;
import se.su.dsv.scipro.peer.PeerReviewRepositoryImpl;
import se.su.dsv.scipro.project.ProjectRepo;
import se.su.dsv.scipro.project.ProjectRepoImpl;
import se.su.dsv.scipro.report.GradingReportTemplateRepo;
import se.su.dsv.scipro.report.GradingReportTemplateRepoImpl;
import se.su.dsv.scipro.report.OppositionReportRepo;
import se.su.dsv.scipro.report.OppositionReportRepoImpl;
import se.su.dsv.scipro.report.SupervisorGradingReportRepository;
import se.su.dsv.scipro.report.SupervisorGradingReportRepositoryImpl;
import se.su.dsv.scipro.reviewing.DecisionRepository;
import se.su.dsv.scipro.reviewing.DecisionRepositoryImpl;
import se.su.dsv.scipro.reviewing.ReviewerTargetRepository;
import se.su.dsv.scipro.reviewing.ReviewerTargetRepositoryImpl;
import se.su.dsv.scipro.system.FooterAddressRepo;
import se.su.dsv.scipro.system.FooterAddressRepoImpl;
import se.su.dsv.scipro.system.FooterLinkRepo;
import se.su.dsv.scipro.system.FooterLinkRepoImpl;
import se.su.dsv.scipro.system.PasswordRepo;
import se.su.dsv.scipro.system.PasswordRepoImpl;
import se.su.dsv.scipro.system.UserRepo;
import se.su.dsv.scipro.system.UserRepoImpl;
public class RepositoryModule extends AbstractModule {
@Override
protected void configure() {
bind(ChecklistQuestionRepo.class).to(ChecklistQuestionRepoImpl.class);
bind(FinalSeminarOppositionRepo.class).to(FinalSeminarOppositionRepoImpl.class);
bind(FinalSeminarActiveParticipationRepository.class).to(FinalSeminarActiveParticipationRepositoryImpl.class);
bind(GradingReportTemplateRepo.class).to(GradingReportTemplateRepoImpl.class);
bind(MilestoneActivityTemplateRepository.class).to(MilestoneActivityTemplateRepositoryImpl.class);
bind(OppositionReportRepo.class).to(OppositionReportRepoImpl.class);
bind(PasswordRepo.class).to(PasswordRepoImpl.class);
bind(ProjectRepo.class).to(ProjectRepoImpl.class);
bind(UserRepo.class).to(UserRepoImpl.class);
bind(PeerReviewRepository.class).to(PeerReviewRepositoryImpl.class);
bind(PeerRequestRepository.class).to(PeerRequestRepositoryImpl.class);
bind(ChecklistCategoryRepo.class).to(ChecklistCategoryRepoImpl.class);
bind(CommentThreadRepo.class).to(CommentThreadRepoImpl.class);
bind(FooterLinkRepo.class).to(FooterLinkRepoImpl.class);
bind(FooterAddressRepo.class).to(FooterAddressRepoImpl.class);
bind(FinalSeminarRepository.class).to(FinalSeminarRepositoryImpl.class);
bind(ReviewerTargetRepository.class).to(ReviewerTargetRepositoryImpl.class);
bind(DecisionRepository.class).to(DecisionRepositoryImpl.class);
bind(SupervisorGradingReportRepository.class).to(SupervisorGradingReportRepositoryImpl.class);
}
}

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
package se.su.dsv.scipro;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.checklist.ChecklistCategory;
import se.su.dsv.scipro.match.ApplicationPeriod;
import se.su.dsv.scipro.match.Keyword;

@ -0,0 +1,285 @@
package se.su.dsv.scipro;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import se.su.dsv.scipro.checklist.ChecklistCategoryRepoImpl;
import se.su.dsv.scipro.checklist.ChecklistQuestionRepoImpl;
import se.su.dsv.scipro.file.FileDescriptionRepoImpl;
import se.su.dsv.scipro.file.FileReferenceRepositoryImpl;
import se.su.dsv.scipro.file.ProjectFileRepositoryImpl;
import se.su.dsv.scipro.finalseminar.AuthorRepositoryImpl;
import se.su.dsv.scipro.finalseminar.FinalSeminarActiveParticipationRepositoryImpl;
import se.su.dsv.scipro.finalseminar.FinalSeminarOppositionRepoImpl;
import se.su.dsv.scipro.finalseminar.FinalSeminarRepositoryImpl;
import se.su.dsv.scipro.forum.AbstractThreadRepositoryImpl;
import se.su.dsv.scipro.forum.ForumPostReadStateRepositoryImpl;
import se.su.dsv.scipro.forum.ForumPostRepositoryImpl;
import se.su.dsv.scipro.forum.GroupThreadRepositoryImpl;
import se.su.dsv.scipro.forum.ProjectThreadRepositoryImpl;
import se.su.dsv.scipro.forum.notifications.ForumNotificationRepositoryImpl;
import se.su.dsv.scipro.grading.GradingHistoryEventRepositoryImpl;
import se.su.dsv.scipro.grading.NationalSubjectCategoryRepositoryImpl;
import se.su.dsv.scipro.grading.PublicationMetadataRepositoryImpl;
import se.su.dsv.scipro.integration.activityfinalseminar.ActivityFinalSeminarRepositoryImpl;
import se.su.dsv.scipro.integration.activityforum.ActivityThreadRepositoryImpl;
import se.su.dsv.scipro.match.FirstMeetingRepositoryImpl;
import se.su.dsv.scipro.match.IdeaRepositoryImpl;
import se.su.dsv.scipro.match.TargetRepositoryImpl;
import se.su.dsv.scipro.milestones.MilestoneActivityTemplateRepositoryImpl;
import se.su.dsv.scipro.notifications.NotificationEventRepositoryImpl;
import se.su.dsv.scipro.peer.CommentThreadRepoImpl;
import se.su.dsv.scipro.peer.PeerRequestRepositoryImpl;
import se.su.dsv.scipro.peer.PeerReviewRepositoryImpl;
import se.su.dsv.scipro.plagiarism.PlagiarismRequestRepositoryImpl;
import se.su.dsv.scipro.plagiarism.urkund.UrkundSettingsRepositoryImpl;
import se.su.dsv.scipro.plagiarism.urkund.UrkundSubmissionRepositoryImpl;
import se.su.dsv.scipro.project.ProjectRepoImpl;
import se.su.dsv.scipro.projectpartner.ProjectPartnerRepositoryImpl;
import se.su.dsv.scipro.report.GradingReportTemplateRepoImpl;
import se.su.dsv.scipro.report.OppositionReportRepoImpl;
import se.su.dsv.scipro.report.SupervisorGradingReportRepositoryImpl;
import se.su.dsv.scipro.reviewing.DecisionRepositoryImpl;
import se.su.dsv.scipro.reviewing.ReviewerDeadlineSettingsRepositoryImpl;
import se.su.dsv.scipro.reviewing.ReviewerTargetRepositoryImpl;
import se.su.dsv.scipro.reviewing.ReviewerThreadRepositoryImpl;
import se.su.dsv.scipro.survey.QuestionRepositoryImpl;
import se.su.dsv.scipro.survey.SurveyRepositoryImpl;
import se.su.dsv.scipro.system.FooterAddressRepoImpl;
import se.su.dsv.scipro.system.FooterLinkRepoImpl;
import se.su.dsv.scipro.system.PasswordRepoImpl;
import se.su.dsv.scipro.system.UserRepoImpl;
@Configuration(proxyBeanMethods = false)
public class RepositoryConfiguration {
@Bean
public GradingHistoryEventRepositoryImpl gradingHistoryEventRepository(Provider<EntityManager> em) {
return new GradingHistoryEventRepositoryImpl(em);
}
@Bean
public AbstractThreadRepositoryImpl abstractThreadRepository(Provider<EntityManager> em) {
return new AbstractThreadRepositoryImpl(em);
}
@Bean
public ActivityFinalSeminarRepositoryImpl activityFinalSeminarRepository(Provider<EntityManager> em) {
return new ActivityFinalSeminarRepositoryImpl(em);
}
@Bean
public ActivityThreadRepositoryImpl activityThreadRepository(Provider<EntityManager> em) {
return new ActivityThreadRepositoryImpl(em);
}
@Bean
public AuthorRepositoryImpl authorRepository(Provider<EntityManager> em) {
return new AuthorRepositoryImpl(em);
}
@Bean
public ChecklistCategoryRepoImpl checklistCategoryRepo(Provider<EntityManager> em) {
return new ChecklistCategoryRepoImpl(em);
}
@Bean
public ChecklistQuestionRepoImpl checklistQuestionRepo(Provider<EntityManager> em) {
return new ChecklistQuestionRepoImpl(em);
}
@Bean
public CommentThreadRepoImpl commentThreadRepo(Provider<EntityManager> em) {
return new CommentThreadRepoImpl(em);
}
@Bean
public DecisionRepositoryImpl decisionRepository(Provider<EntityManager> em) {
return new DecisionRepositoryImpl(em);
}
@Bean
public FileDescriptionRepoImpl fileDescriptionRepo(Provider<EntityManager> em) {
return new FileDescriptionRepoImpl(em);
}
@Bean
public FinalSeminarActiveParticipationRepositoryImpl finalSeminarActiveParticipationRepository(Provider<EntityManager> em) {
return new FinalSeminarActiveParticipationRepositoryImpl(em);
}
@Bean
public FinalSeminarRepositoryImpl finalSeminarRepository(Provider<EntityManager> em) {
return new FinalSeminarRepositoryImpl(em);
}
@Bean
public FileReferenceRepositoryImpl fileReferenceRepository(Provider<EntityManager> em) {
return new FileReferenceRepositoryImpl(em);
}
@Bean
public FinalSeminarOppositionRepoImpl finalSeminarOppositionRepo(Provider<EntityManager> em) {
return new FinalSeminarOppositionRepoImpl(em);
}
@Bean
public FirstMeetingRepositoryImpl firstMeetingRepository(Provider<EntityManager> em) {
return new FirstMeetingRepositoryImpl(em);
}
@Bean
public FooterAddressRepoImpl footerAddressRepo(Provider<EntityManager> em) {
return new FooterAddressRepoImpl(em);
}
@Bean
public FooterLinkRepoImpl footerLinkRepo(Provider<EntityManager> em) {
return new FooterLinkRepoImpl(em);
}
@Bean
public ForumNotificationRepositoryImpl forumNotificationRepository(Provider<EntityManager> em) {
return new ForumNotificationRepositoryImpl(em);
}
@Bean
public ForumPostReadStateRepositoryImpl forumPostReadStateRepository(Provider<EntityManager> em) {
return new ForumPostReadStateRepositoryImpl(em);
}
@Bean
public ForumPostRepositoryImpl forumPostRepository(Provider<EntityManager> em) {
return new ForumPostRepositoryImpl(em);
}
@Bean
public GradingReportTemplateRepoImpl gradingReportTemplateRepo(Provider<EntityManager> em) {
return new GradingReportTemplateRepoImpl(em);
}
@Bean
public GroupThreadRepositoryImpl groupThreadRepository(Provider<EntityManager> em) {
return new GroupThreadRepositoryImpl(em);
}
@Bean
public IdeaRepositoryImpl ideaRepository(Provider<EntityManager> em) {
return new IdeaRepositoryImpl(em);
}
@Bean
public MilestoneActivityTemplateRepositoryImpl milestoneActivityTemplateRepository(Provider<EntityManager> em) {
return new MilestoneActivityTemplateRepositoryImpl(em);
}
@Bean
public NationalSubjectCategoryRepositoryImpl nationalSubjectCategoryRepository(Provider<EntityManager> em) {
return new NationalSubjectCategoryRepositoryImpl(em);
}
@Bean
public OppositionReportRepoImpl oppositionReportRepo(Provider<EntityManager> em) {
return new OppositionReportRepoImpl(em);
}
@Bean
public PasswordRepoImpl passwordRepo(Provider<EntityManager> em) {
return new PasswordRepoImpl(em);
}
@Bean
public PeerRequestRepositoryImpl peerRequestRepository(Provider<EntityManager> em) {
return new PeerRequestRepositoryImpl(em);
}
@Bean
public PeerReviewRepositoryImpl peerReviewRepository(Provider<EntityManager> em) {
return new PeerReviewRepositoryImpl(em);
}
@Bean
public ProjectPartnerRepositoryImpl projectPartnerRepository(Provider<EntityManager> em) {
return new ProjectPartnerRepositoryImpl(em);
}
@Bean
public ProjectRepoImpl projectRepo(Provider<EntityManager> em) {
return new ProjectRepoImpl(em);
}
@Bean
public ProjectThreadRepositoryImpl projectThreadRepository(Provider<EntityManager> em) {
return new ProjectThreadRepositoryImpl(em);
}
@Bean
public PublicationMetadataRepositoryImpl publicationMetadataRepository(Provider<EntityManager> em) {
return new PublicationMetadataRepositoryImpl(em);
}
@Bean
public QuestionRepositoryImpl questionRepository(Provider<EntityManager> em) {
return new QuestionRepositoryImpl(em);
}
@Bean
public ReviewerDeadlineSettingsRepositoryImpl reviewerDeadlineSettingsRepository(Provider<EntityManager> em) {
return new ReviewerDeadlineSettingsRepositoryImpl(em);
}
@Bean
public ReviewerTargetRepositoryImpl reviewerTargetRepository(Provider<EntityManager> em) {
return new ReviewerTargetRepositoryImpl(em);
}
@Bean
public ReviewerThreadRepositoryImpl reviewerThreadRepository(Provider<EntityManager> em) {
return new ReviewerThreadRepositoryImpl(em);
}
@Bean
public SurveyRepositoryImpl surveyRepository(Provider<EntityManager> em) {
return new SurveyRepositoryImpl(em);
}
@Bean
public TargetRepositoryImpl targetRepository(Provider<EntityManager> em) {
return new TargetRepositoryImpl(em);
}
@Bean
public UrkundSettingsRepositoryImpl urkundSettingsRepository(Provider<EntityManager> em) {
return new UrkundSettingsRepositoryImpl(em);
}
@Bean
public UrkundSubmissionRepositoryImpl urkundSubmissionRepository(Provider<EntityManager> em) {
return new UrkundSubmissionRepositoryImpl(em);
}
@Bean
public UserRepoImpl userRepo(Provider<EntityManager> em) {
return new UserRepoImpl(em);
}
@Bean
public PlagiarismRequestRepositoryImpl plagiarismRequestRepository(Provider<EntityManager> em) {
return new PlagiarismRequestRepositoryImpl(em);
}
@Bean
public ProjectFileRepositoryImpl projectFileRepository(Provider<EntityManager> em) {
return new ProjectFileRepositoryImpl(em);
}
@Bean
public NotificationEventRepositoryImpl notificationEventRepository(Provider<EntityManager> em) {
return new NotificationEventRepositoryImpl(em);
}
@Bean
public SupervisorGradingReportRepositoryImpl supervisorGradingReportRepository(Provider<EntityManager> em) {
return new SupervisorGradingReportRepositoryImpl(em);
}
}

@ -1,140 +1,164 @@
package se.su.dsv.scipro.activityplan;
import com.querydsl.core.annotations.QueryInit;
import jakarta.persistence.GenerationType;
import se.su.dsv.scipro.checklist.Checklist;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.system.LazyDeletableDomainObject;
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.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 java.io.Serializable;
import java.util.*;
import java.util.Comparator;
import java.util.Date;
import java.util.Objects;
@Entity
@Table(name = "activity")
@Cacheable(true)
public class Activity extends LazyDeletableDomainObject {
@Id
public static IActivityPlan builder(){
return new Builder();
}
//<editor-fold desc="Basic JPA-mappings">
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(optional=false)
@JoinColumn (name="activityTemplate_id")
@QueryInit("project")
private ActivityPlan activityPlan;
@Basic
@Column(name = "title", nullable=false)
private String title;
@Column(nullable=false)
private Date date;
@Basic
@Column(name = "date", nullable=false)
private Date date;
@Column(nullable=false)
private String title;
private String description;
@OneToOne(optional = true, cascade = CascadeType.ALL)
@JoinColumn(name = "file_upload_reference_id")
private FileReference fileUpload;
@ManyToOne
private Checklist checklist;
@Basic
@Column(name = "description")
private String description;
@Basic
@Column(name = "editable")
private boolean editable = true;
@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")
@QueryInit("project")
private ActivityPlan activityPlan;
@ManyToOne
@JoinColumn(name = "checklist_id", referencedColumnName = "id")
private Checklist checklist;
@OneToOne(optional = true, cascade = CascadeType.ALL)
@JoinColumn(name = "upload_file_reference_id", referencedColumnName = "id")
private FileReference fileUpload;
//</editor-fold>
//<editor-fold desc="Constructor">
public Activity() {
this.title = "";
this.description = "";
}
//</editor-fold>
@Override
public String toString(){
return "Event: "+ getTitle()+"@"+getDate();
}
@Override
//<editor-fold desc="Properties (Getters and Setters)">
@Override
public Long getId() {
return this.id;
}
public ActivityPlan getActivityPlan() {
return this.activityPlan;
}
public Date getDate() {
return this.date;
}
public String getTitle() {
return this.title;
}
public String getDescription() {
return this.description;
}
public FileReference getFileUpload() {
return this.fileUpload;
}
public Checklist getChecklist() {
return this.checklist;
}
public boolean isEditable() {
return this.editable;
}
public Action getAction() {
return this.action;
}
public void setId(Long id) {
this.id = id;
}
public void setActivityPlan(ActivityPlan activityPlan) {
this.activityPlan = activityPlan;
}
public void setDate(Date date) {
this.date = date;
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getDate() {
return this.date;
}
public void setDate(Date date) {
this.date = date;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public void setFileUpload(FileReference fileUpload) {
this.fileUpload = fileUpload;
}
public void setChecklist(Checklist checklist) {
this.checklist = checklist;
public boolean isEditable() {
return this.editable;
}
public void setEditable(boolean editable) {
this.editable = editable;
}
public Action getAction() {
return this.action;
}
public void setAction(Action action) {
this.action = action;
}
public ActivityPlan getActivityPlan() {
return this.activityPlan;
}
public void setActivityPlan(ActivityPlan activityPlan) {
this.activityPlan = activityPlan;
}
public Checklist getChecklist() {
return this.checklist;
}
public void setChecklist(Checklist checklist) {
this.checklist = checklist;
}
public FileReference getFileUpload() {
return this.fileUpload;
}
public void setFileUpload(FileReference fileUpload) {
this.fileUpload = fileUpload;
}
//</editor-fold>
//<editor-fold desc="Methods Common To All Objects">
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -144,15 +168,24 @@ public class Activity extends LazyDeletableDomainObject {
&& Objects.equals(this.getId(), other.getId());
}
protected boolean canEqual(final Object other) {
return other instanceof Activity;
@Override
public int hashCode() {
return Objects.hashCode(getId());
}
@Override
public int hashCode() {
return Objects.hashCode(getId());
}
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) {
@ -209,10 +242,6 @@ public class Activity extends LazyDeletableDomainObject {
}
}
public static IActivityPlan builder(){
return new Builder();
}
public interface IActivityPlan {
IDate activityPlan(ActivityPlan activityPlan);
}
@ -233,4 +262,5 @@ public class Activity extends LazyDeletableDomainObject {
IBuild editable(boolean editable);
Activity build();
}
//</editor-fold>
}

@ -1,67 +1,92 @@
package se.su.dsv.scipro.activityplan;
import jakarta.persistence.Basic;
import jakarta.persistence.Cacheable;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
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 se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.DomainObject;
import jakarta.persistence.*;
import java.util.Date;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
@Entity
@Table(name ="activity_plan")
@Cacheable(true)
public class ActivityPlan extends DomainObject {
public static IProject builder() {
return new Builder();
}
//<editor-fold desc="Basic JPA-mappings">
@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)
@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());
@OneToOne(optional=false)
private Project project;
private Date startDate;
//</editor-fold>
//<editor-fold desc="Properties (Getters and Setters)">
@Override
public Long getId() {
return this.id;
}
public Set<Activity> getActivities() {
return this.activities;
}
public Project getProject() {
return this.project;
}
public Date getStartDate() {
return this.startDate;
}
public void setId(Long id) {
this.id = id;
}
public void setActivities(Set<Activity> activities) {
this.activities = activities;
}
public void setProject(Project project) {
this.project = project;
public Date getStartDate() {
return this.startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
@Override
public String toString() {
return "ActivityPlan(id=" + this.getId() + ", activities=" + this.getActivities() + ", project=" + this.getProject() + ", startDate=" + this.getStartDate() + ")";
public Project getProject() {
return this.project;
}
public void setProject(Project project) {
this.project = project;
}
public Set<Activity> getActivities() {
return this.activities;
}
public void setActivities(Set<Activity> activities) {
this.activities = activities;
}
//</editor-fold>
//<editor-fold desc="Methods Common To All Objects">
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -74,15 +99,25 @@ public class ActivityPlan extends DomainObject {
&& Objects.equals(this.getStartDate(), other.getStartDate());
}
protected boolean canEqual(final Object other) {
return other instanceof ActivityPlan;
}
@Override
public int hashCode() {
return Objects.hash(this.getId(), this.getActivities(), this.getProject(), this.getStartDate());
}
@Override
public String toString() {
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;
@ -100,10 +135,6 @@ public class ActivityPlan extends DomainObject {
}
}
public static IProject builder() {
return new Builder();
}
public interface IProject {
IBuild project(Project project);
}
@ -111,4 +142,5 @@ public class ActivityPlan extends DomainObject {
public interface IBuild {
ActivityPlan build();
}
//</editor-fold>
}

@ -1,7 +1,7 @@
package se.su.dsv.scipro.activityplan;
import com.google.common.eventbus.EventBus;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.su.dsv.scipro.system.Pageable;

@ -1,98 +1,117 @@
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;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Lob;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderColumn;
import jakarta.persistence.Table;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
import jakarta.persistence.*;
import java.util.*;
@Entity
@Table(name = "activity_plan_template")
@Cacheable(true)
public class ActivityPlanTemplate extends DomainObject {
//<editor-fold desc="Basic JPA-mappings">
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OrderColumn(name = "numberInOrder")
@OneToMany(mappedBy="activityPlanTemplate", orphanRemoval=true, cascade=CascadeType.ALL)
private List<ActivityTemplate> activityTemplates = new ArrayList<>();
public List<ActivityTemplate> getActivityTemplates(){
return Collections.unmodifiableList(activityTemplates);
}
public void setActivityTemplates(List<ActivityTemplate> activityTemplates){
this.activityTemplates = new ArrayList<>(activityTemplates);
}
@ManyToOne(optional=false)
private User creator;
@Column(nullable=false)
private String title;
@Lob
private String description;
@Column(nullable=false)
@Basic
@Column(name = "is_sys_admin_template", nullable=false)
private boolean isSysAdminTemplate = false;
public void addActivity(ActivityTemplate activity){
activity.setActivityPlanTemplate(this);
activity.setNumberInOrder(activityTemplates.size());
activityTemplates.add(activity);
}
@Basic
@Column(name = "title", nullable = false)
private String title;
public void clearActivities(){
activityTemplates.clear();
}
@Basic
@Column(name = "description")
@Lob
private String description;
//</editor-fold>
public void addActivities(final Collection<ActivityTemplate> activities){
activityTemplates.addAll(activities);
}
//<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>
@Override
//<editor-fold desc="JPA-mappings of other tables referencing to this table 'activity_plan_template'">
@OneToMany(mappedBy="activityPlanTemplate", orphanRemoval=true, cascade=CascadeType.ALL)
@OrderColumn(name = "number_in_order")
private List<ActivityTemplate> activityTemplates = new ArrayList<>();
//</editor-fold>
//<editor-fold desc="Properties (Getters and Setters)">
@Override
public Long getId() {
return this.id;
}
public User getCreator() {
return this.creator;
}
public String getTitle() {
return this.title;
}
public String getDescription() {
return this.description;
}
public boolean isSysAdminTemplate() {
return this.isSysAdminTemplate;
}
public void setId(Long id) {
this.id = id;
}
public void setCreator(User creator) {
this.creator = creator;
}
public void setTitle(String title) {
this.title = title;
}
public void setDescription(String description) {
this.description = description;
public boolean isSysAdminTemplate() {
return this.isSysAdminTemplate;
}
public void setSysAdminTemplate(boolean isSysAdminTemplate) {
this.isSysAdminTemplate = isSysAdminTemplate;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public User getCreator() {
return this.creator;
}
public void setCreator(User creator) {
this.creator = creator;
}
public List<ActivityTemplate> getActivityTemplates(){
return Collections.unmodifiableList(activityTemplates);
}
public void setActivityTemplates(List<ActivityTemplate> activityTemplates){
this.activityTemplates = new ArrayList<>(activityTemplates);
}
//</editor-fold>
//<editor-fold desc="Methods Common To All Objects">
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -119,6 +138,25 @@ public class ActivityPlanTemplate extends DomainObject {
@Override
public String toString() {
return "ActivityPlanTemplate(id=" + this.getId() + ", creator=" + this.getCreator() + ", title=" + this.getTitle() + ", description=" + this.getDescription() + ", isSysAdminTemplate=" + this.isSysAdminTemplate() + ")";
return "ActivityPlanTemplate(id=" + this.getId() + ", creator=" + this.getCreator() +
", title=" + this.getTitle() + ", description=" + this.getDescription() +
", isSysAdminTemplate=" + this.isSysAdminTemplate() + ")";
}
//</editor-fold>
//<editor-fold desc="Other methods">
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,116 +1,142 @@
package se.su.dsv.scipro.activityplan;
import java.util.Objects;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
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.Lob;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import se.su.dsv.scipro.checklist.ChecklistTemplate;
import se.su.dsv.scipro.system.DomainObject;
import jakarta.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "activity_template")
public class ActivityTemplate extends DomainObject {
//<editor-fold desc="Basic JPA-mappings">
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
@Basic
@Column(name = "title", nullable = false)
private String title;
@Basic
@Column(name = "description")
@Lob
private String description;
@ManyToOne
private ActivityPlanTemplate activityPlanTemplate;
@Column(nullable = false)
@Basic
@Column(name = "days_offset", nullable = false)
private int daysOffset;
@Basic
@Column(name = "action")
@Enumerated(EnumType.STRING)
private Action action = Action.NONE;
@Column(nullable = false)
@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.">
@ManyToOne
@JoinColumn(name = "activity_plan_template_id", referencedColumnName = "id")
private ActivityPlanTemplate activityPlanTemplate;
@ManyToOne(optional = true)
@JoinColumn(name = "checklist_template_id", referencedColumnName = "id")
private ChecklistTemplate checklistTemplate;
//</editor-fold>
//<editor-fold desc="Constructors">
public ActivityTemplate() {
}
public ActivityTemplate(int daysOffset) {
this.daysOffset = daysOffset;
}
//</editor-fold>
public int getDaysOffset() {
return daysOffset;
}
public int getNumberInOrder() {
return numberInOrder;
}
//<editor-fold desc="Properties (Getters and Setters">
@Override
public Long getId() {
return this.id;
}
public String getTitle() {
return this.title;
}
public String getDescription() {
return this.description;
}
public ActivityPlanTemplate getActivityPlanTemplate() {
return this.activityPlanTemplate;
}
public Action getAction() {
return this.action;
}
public ChecklistTemplate getChecklistTemplate() {
return this.checklistTemplate;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public void setActivityPlanTemplate(ActivityPlanTemplate activityPlanTemplate) {
this.activityPlanTemplate = activityPlanTemplate;
public int getDaysOffset() {
return daysOffset;
}
public void setDaysOffset(int daysOffset) {
this.daysOffset = daysOffset;
}
public Action getAction() {
return this.action;
}
public void setAction(Action action) {
this.action = action;
}
public int getNumberInOrder() {
return numberInOrder;
}
public void setNumberInOrder(int numberInOrder) {
this.numberInOrder = numberInOrder;
}
public ActivityPlanTemplate getActivityPlanTemplate() {
return this.activityPlanTemplate;
}
public void setActivityPlanTemplate(ActivityPlanTemplate activityPlanTemplate) {
this.activityPlanTemplate = activityPlanTemplate;
}
public ChecklistTemplate getChecklistTemplate() {
return this.checklistTemplate;
}
public void setChecklistTemplate(ChecklistTemplate checklistTemplate) {
this.checklistTemplate = checklistTemplate;
}
//</editor-fold>
@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() + ")";
}
//<editor-fold desc="Methods Common To All Objects">
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -120,12 +146,24 @@ public class ActivityTemplate extends DomainObject {
&& Objects.equals(this.getId(), other.getId());
}
protected boolean canEqual(final Object other) {
return other instanceof ActivityTemplate;
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
}
}
@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() + ")";
}
//</editor-fold>
//<editor-fold desc="Other methods">
protected boolean canEqual(final Object other) {
return other instanceof ActivityTemplate;
}
//</editor-fold>
}

@ -1,12 +1,33 @@
package se.su.dsv.scipro.checklist;
import jakarta.persistence.Basic;
import jakarta.persistence.Cacheable;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
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 jakarta.persistence.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@Entity
@Table(name = "checklist")
@ -17,6 +38,7 @@ public class Checklist extends DomainObject {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Basic
@Column(nullable = false)
private String name;
@ -28,15 +50,26 @@ public class Checklist extends DomainObject {
*/
@Deprecated
@ManyToOne(optional = false)
@JoinColumn(name = "project_id")
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"))
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"))
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
@MapKeyJoinColumn(name = "user_id")
private Map<User, Date> userLastOpenDate = new HashMap<>();
protected Checklist() {

@ -1,29 +1,54 @@
package se.su.dsv.scipro.checklist;
import java.util.Objects;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
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.Lob;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
import jakarta.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "checklist_answer")
public class ChecklistAnswer extends DomainObject {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Basic
@Column(name = "answer", nullable = false)
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private ChecklistAnswerEnum answer;
@ManyToOne(optional = false)
private User user;
@Basic
@Column(name = "comment")
@Lob
@Column
private String comment;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (checklist_answer) referencing other
// tables.
// ----------------------------------------------------------------------------------
@ManyToOne(optional = false)
@JoinColumn(name = "user_id", referencedColumnName = "id")
private User user;
// ----------------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------------
protected ChecklistAnswer() {
}
@ -36,44 +61,45 @@ public class ChecklistAnswer extends DomainObject {
this.answer = answer != null ? answer : ChecklistAnswerEnum.NO_ANSWER;
}
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
@Override
public Long getId() {
return this.id;
}
public ChecklistAnswerEnum getAnswer() {
return this.answer;
}
public User getUser() {
return this.user;
}
public String getComment() {
return this.comment;
}
public void setId(Long id) {
this.id = id;
}
public ChecklistAnswerEnum getAnswer() {
return this.answer;
}
public void setAnswer(ChecklistAnswerEnum answer) {
this.answer = answer;
}
public void setUser(User user) {
this.user = user;
public String getComment() {
return this.comment;
}
public void setComment(String comment) {
this.comment = comment;
}
@Override
public String toString() {
return "ChecklistAnswer(id=" + this.getId() + ", answer=" + this.getAnswer() + ", user=" + this.getUser() + ", comment=" + this.getComment() + ")";
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -83,12 +109,21 @@ public class ChecklistAnswer extends DomainObject {
&& Objects.equals(this.getId(), other.getId());
}
protected boolean canEqual(final Object other) {
return other instanceof ChecklistAnswer;
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
}
@Override
public String toString() {
return "ChecklistAnswer(id=" + this.getId() + ", answer=" + this.getAnswer() + ", user=" + this.getUser() +
", comment=" + this.getComment() + ")";
}
// ----------------------------------------------------------------------------------
// Other Methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof ChecklistAnswer;
}
}

@ -4,6 +4,6 @@ public enum ChecklistAnswerEnum {
RED,
GREEN,
YELLOW,
NOT_APLICABLE,
NOT_APPLICABLE,
NO_ANSWER
}

@ -9,7 +9,7 @@ import jakarta.persistence.EntityManager;
public class ChecklistAnswerServiceImpl extends AbstractServiceImpl<ChecklistAnswer, Long> implements ChecklistAnswerService {
@Inject
protected ChecklistAnswerServiceImpl(Provider<EntityManager> em) {
public ChecklistAnswerServiceImpl(Provider<EntityManager> em) {
super(em, ChecklistAnswer.class, QChecklistAnswer.checklistAnswer);
}
}

@ -1,13 +1,17 @@
/**
*
*/
package se.su.dsv.scipro.checklist;
import se.su.dsv.scipro.system.DomainObject;
import jakarta.persistence.*;
import java.util.Objects;
import jakarta.persistence.Cacheable;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import se.su.dsv.scipro.system.DomainObject;
@Entity
@Table(name="checklist_category")
@Cacheable(true)
@ -16,7 +20,7 @@ public class ChecklistCategory extends DomainObject {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique=true)
@Column(name = "category_name", unique = true)
private String categoryName;
protected ChecklistCategory() {

@ -1,6 +1,6 @@
package se.su.dsv.scipro.checklist;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;

@ -1,13 +1,26 @@
package se.su.dsv.scipro.checklist;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
import jakarta.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import jakarta.persistence.Basic;
import jakarta.persistence.Cacheable;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.Lob;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
@Entity
@Table(name = "checklist_question")
@Cacheable(true)
@ -20,13 +33,15 @@ public class ChecklistQuestion extends DomainObject {
@Column(nullable = false)
private String question;
@Column(nullable = false)
@Basic
@Column(name = "question_number", nullable = false)
private int questionNumber;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(
joinColumns = @JoinColumn(name = "checklist_question_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() {

@ -1,6 +1,6 @@
package se.su.dsv.scipro.checklist;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;

@ -1,6 +1,6 @@
package se.su.dsv.scipro.checklist;
import com.google.inject.persist.Transactional;
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;

@ -1,11 +1,27 @@
package se.su.dsv.scipro.checklist;
import jakarta.persistence.Basic;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
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 jakarta.persistence.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name = "checklist_template")
@ -17,35 +33,42 @@ public class ChecklistTemplate extends DomainObject {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Basic
@Column(nullable = false)
private String name;
@Basic(optional = true)
@Column(name = "description")
private String description;
@Column
@Basic
@Column(name = "template_number")
private int templateNumber = DEFAULT_TEMPLATE_NUMBER;
@Lob
@ElementCollection
@CollectionTable(name = "checklist_template_question",
joinColumns = @JoinColumn(name = "checklist_template_id"))
@Column(name = "question")
private List<String> questions = new ArrayList<>(1);
@ManyToOne(optional = false)
@JoinColumn(name = "creator_user_id", referencedColumnName = "id")
private User creator;
@ManyToMany
@JoinTable(
joinColumns = @JoinColumn(name = "checklist_template_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_ProjectType",
@JoinTable(name = "checklist_template_project_type",
joinColumns = {@JoinColumn(name = "checklist_template_id")},
inverseJoinColumns = {@JoinColumn(name = "projectType_id")})
inverseJoinColumns = {@JoinColumn(name = "project_type_id")})
private Collection<ProjectType> projectTypes = new HashSet<>();
public ChecklistTemplate() {
}
public ChecklistTemplate(String name, User creator) {

@ -1,6 +1,6 @@
package se.su.dsv.scipro.checklist;
import com.google.inject.persist.Transactional;
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;

@ -1,20 +0,0 @@
package se.su.dsv.scipro.daisyExternal;
import com.google.inject.Key;
import com.google.inject.PrivateModule;
import com.google.inject.Scopes;
import com.google.inject.name.Names;
import se.su.dsv.scipro.daisyExternal.http.DaisyAPI;
import se.su.dsv.scipro.daisyExternal.http.DaisyAPIImpl;
public class DaisyExternalModule extends PrivateModule {
@Override
protected void configure() {
requireBinding(Key.get(String.class, Names.named("daisy.api.url")));
requireBinding(Key.get(String.class, Names.named("daisy.api.username")));
requireBinding(Key.get(String.class, Names.named("daisy.api.password")));
bind(DaisyAPI.class).to(DaisyAPIImpl.class).in(Scopes.SINGLETON);
expose(DaisyAPI.class);
}
}

@ -1,15 +0,0 @@
package se.su.dsv.scipro.events;
import com.google.common.eventbus.EventBus;
import com.google.inject.AbstractModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EventModule extends AbstractModule {
private static final Logger LOGGER = LoggerFactory.getLogger(EventModule.class);
@Override
protected void configure() {
bind(EventBus.class).toInstance(new EventBus((throwable, context) -> LOGGER.error("Could not dispatch event: " + context.getSubscriber() + " to " + context.getSubscriberMethod(), throwable)));
}
}

@ -33,25 +33,40 @@ public class FileDescription extends DomainObject {
public static final int FILES_PER_SUBDIRECTORY = 1000;
public static final String FILE_ROOT = "/scipro-files";
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
@Basic
@Column(name = "name")
private String name;
@Column
@Basic
@Column(name = "mime_type")
private String mimeType;
@Column
private String identifier;
@ManyToOne
@JoinColumn(name = "userId")
private User uploader;
@Basic
@Column(name = "size")
private long size;
@Basic
@Column(name = "file_identifier")
private String identifier;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (file_description) referencing
// other tables.
// ----------------------------------------------------------------------------------
@ManyToOne
@JoinColumn(name = "user_id", referencedColumnName = "id")
private User uploader;
// ----------------------------------------------------------------------------------
// JPA lifecycle methods
// ----------------------------------------------------------------------------------
@PostRemove
void removeActualData() {
try {
@ -63,6 +78,96 @@ public class FileDescription extends DomainObject {
}
}
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
@Override
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMimeType() {
return this.mimeType;
}
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
public long getSize() {
return this.size;
}
public void setSize(long size) {
this.size = size;
}
public String getIdentifier() {
return this.identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public User getUploader() {
return this.uploader;
}
public void setUploader(User uploader) {
this.uploader = uploader;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
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());
}
@Override
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $id = this.getId();
result = result * PRIME + ($id == null ? 43 : $id.hashCode());
return result;
}
// Todo
@Override
public String toString() {
if (name != null) {
return name;
} else {
return super.toString();
}
}
// ----------------------------------------------------------------------------------
// Other methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof FileDescription;
}
public Path getPath0() {
return FileSystems.getDefault().getPath(FILE_ROOT, getSubdirectory(), Long.toString(id));
}
@ -78,85 +183,4 @@ public class FileDescription extends DomainObject {
public InputStream getData() throws IOException {
return Files.newInputStream(getPath0());
}
public String getName() {
return name;
}
// Todo
@Override
public String toString() {
if (name != null) {
return name;
} else {
return super.toString();
}
}
@Override
public Long getId() {
return this.id;
}
public String getMimeType() {
return this.mimeType;
}
public String getIdentifier() {
return this.identifier;
}
public User getUploader() {
return this.uploader;
}
public long getSize() {
return this.size;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public void setUploader(User uploader) {
this.uploader = uploader;
}
public void setSize(long size) {
this.size = size;
}
@Override
public boolean equals(final Object o) {
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());
}
protected boolean canEqual(final Object other) {
return other instanceof FileDescription;
}
@Override
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $id = this.getId();
result = result * PRIME + ($id == null ? 43 : $id.hashCode());
return result;
}
}

@ -1,6 +1,6 @@
package se.su.dsv.scipro.file;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;

@ -1,16 +0,0 @@
package se.su.dsv.scipro.file;
import com.google.inject.AbstractModule;
public class FileModule extends AbstractModule {
@Override
protected void configure() {
bind(FileService.class).to(FileServiceImpl.class);
bind(ProjectFileService.class).to(ProjectFileServiceImpl.class);
bind(ProjectFileRepository.class).to(ProjectFileRepositoryImpl.class);
bind(FileReferenceRepository.class).to(FileReferenceRepositoryImpl.class);
bind(FileDescriptionRepo.class).to(FileDescriptionRepoImpl.class);
requireBinding(FileStore.class);
}
}

@ -9,7 +9,7 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.io.Serializable;
import java.util.*;
import java.util.Objects;
/**
* A reference to a file.
@ -29,7 +29,7 @@ public class FileReference implements Serializable {
private Long id;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "file_description_id")
@JoinColumn(name = "file_description_id", referencedColumnName = "id")
private FileDescription fileDescription;
public Long getId() {

@ -1,6 +1,6 @@
package se.su.dsv.scipro.file;
interface FileReferenceRepository {
public interface FileReferenceRepository {
FileReference create(FileReference fileReference);
void delete(FileReference fileReference);

@ -1,16 +1,16 @@
package se.su.dsv.scipro.file;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractRepository;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
class FileReferenceRepositoryImpl extends AbstractRepository implements FileReferenceRepository {
public class FileReferenceRepositoryImpl extends AbstractRepository implements FileReferenceRepository {
@Inject
FileReferenceRepositoryImpl(final Provider<EntityManager> em) {
public FileReferenceRepositoryImpl(final Provider<EntityManager> em) {
super(em);
}

@ -1,6 +1,6 @@
package se.su.dsv.scipro.file;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;

@ -1,71 +1,88 @@
package se.su.dsv.scipro.file;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
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.ManyToOne;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.DomainObject;
import jakarta.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "project_file")
public class ProjectFile extends DomainObject {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private Project project;
@Basic
@Column(name = "file_source")
@Enumerated(EnumType.STRING)
private FileSource fileSource = FileSource.FILES;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (project_file) referencing other tables.
// ----------------------------------------------------------------------------------
@ManyToOne
@JoinColumn(name = "project_id", referencedColumnName = "id")
private Project project;
@OneToOne
@JoinColumn(name = "file_reference_id")
@JoinColumn(name = "file_reference_id", referencedColumnName = "id")
private FileReference fileReference;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
@Override
public Long getId() {
return this.id;
}
public Project getProject() {
return this.project;
}
public FileSource getFileSource() {
return this.fileSource;
}
public FileDescription getFileDescription() {
return this.fileReference.getFileDescription();
}
public void setId(Long id) {
this.id = id;
}
public void setProject(Project project) {
this.project = project;
public FileSource getFileSource() {
return this.fileSource;
}
public void setFileSource(FileSource fileSource) {
this.fileSource = fileSource;
}
public void setFileReference(FileReference fileReference) {
this.fileReference = fileReference;
}
public FileReference getFileReference() {
return this.fileReference;
}
@Override
public String toString() {
return "ProjectFile(id=" + this.getId() + ", project=" + this.getProject() + ", fileSource=" + this.getFileSource() + ", fileDescription=" + this.getFileDescription() + ")";
public void setFileReference(FileReference fileReference) {
this.fileReference = fileReference;
}
public Project getProject() {
return this.project;
}
public void setProject(Project project) {
this.project = project;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -79,12 +96,24 @@ public class ProjectFile extends DomainObject {
&& Objects.equals(this.getFileDescription(), other.getFileDescription());
}
protected boolean canEqual(final Object other) {
return other instanceof ProjectFile;
}
@Override
public int hashCode() {
return Objects.hash(this.getId(), this.getProject(), this.getFileSource(), this.getFileDescription());
}
@Override
public String toString() {
return "ProjectFile(id=" + this.getId() + ", project=" + this.getProject() + ", fileSource=" + this.getFileSource() + ", fileDescription=" + this.getFileDescription() + ")";
}
// ----------------------------------------------------------------------------------
// Other methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof ProjectFile;
}
public FileDescription getFileDescription() {
return this.fileReference.getFileDescription();
}
}

@ -1,6 +1,6 @@
package se.su.dsv.scipro.file;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project;

@ -23,7 +23,15 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "final_seminar")
@ -35,27 +43,69 @@ public class FinalSeminar extends LazyDeletableDomainObject {
public static final int DEFAULT_MAX_PARTICIPANTS = 5;
public static final String FINAL_SEMINAR = "finalSeminar";
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(optional = false)
@QueryInit({"projectType", "headSupervisor"})
private Project project;
@Basic(optional = false)
@Column(name = "start_date")
private Date startDate;
@Basic(optional = false)
@Column(name = "room")
private String room;
@Basic
@Column(name = "max_opponents")
private int maxOpponents = DEFAULT_MAX_OPPONENTS;
@Basic
@Column(name = "max_participants")
private int maxParticipants = DEFAULT_MAX_PARTICIPANTS;
@Enumerated(EnumType.STRING)
@Column(name = "presentation_lang")
private Language presentationLanguage;
@Basic
@Column(name = "document_upload_date")
private Date documentUploadDate;
@Basic
@Column(name = "extra_info")
private String extraInfo;
@Basic
@Column(name = "creation_reason")
private String creationReason;
@Basic
@Column(name = "manual_participants")
private Boolean manualParticipants = false;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (final_seminar) referencing other tables.
// ----------------------------------------------------------------------------------
/*
* Cascading delete, set document to nul will delete the filedescription but
* not the actual file. Use FinarSeminarUploadController.deleteSeminarReport
* to delete the document
*/
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "document_file_reference_id", referencedColumnName = "id")
private FileReference document;
@OneToOne(optional = false)
@JoinColumn(name = "project_id", referencedColumnName = "id")
@QueryInit({"projectType", "headSupervisor"})
private Project project;
// ----------------------------------------------------------------------------------
// JPA-mappings of other tables referencing to this table "final_seminar"
// ----------------------------------------------------------------------------------
@OneToMany(mappedBy = FINAL_SEMINAR, orphanRemoval = true, cascade = CascadeType.ALL)
private Set<FinalSeminarActiveParticipation> activeParticipations = new HashSet<>();
@ -65,28 +115,10 @@ public class FinalSeminar extends LazyDeletableDomainObject {
@OneToMany(mappedBy = FINAL_SEMINAR, orphanRemoval = true, cascade = CascadeType.ALL)
private Set<FinalSeminarRespondent> respondents = new HashSet<>();
/*
* Cascading delete, set document to nul will delete the filedescription but
* not the actual file. Use FinarSeminarUploadController.deleteSeminarReport
* to delete the document
*/
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "document_reference_id")
private FileReference document;
private Date documentUploadDate;
@Enumerated(EnumType.STRING)
private Language presentationLanguage;
private int maxOpponents = DEFAULT_MAX_OPPONENTS;
private int maxParticipants = DEFAULT_MAX_PARTICIPANTS;
@Basic
private String creationReason;
// ----------------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------------
public FinalSeminar() {
}
public FinalSeminar(int maxOpponents, int maxParticipants) {
@ -99,6 +131,90 @@ public class FinalSeminar extends LazyDeletableDomainObject {
this.project = project;
}
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
@Override
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isCancelled() {
return isDeleted();
}
public void setCancelled(boolean cancelled) {
setDeleted(cancelled);
}
public Date getStartDate() {
return this.startDate;
}
public void setStartDate(Date startDate) {
this.startDate = (Date) startDate.clone();
}
public String getRoom() {
return this.room;
}
public void setRoom(String room) {
this.room = room;
}
public int getMaxOpponents() {
return this.maxOpponents;
}
public void setMaxOpponents(int maxOpponents) {
this.maxOpponents = maxOpponents;
}
public int getMaxParticipants() {
return this.maxParticipants;
}
public void setMaxParticipants(int maxParticipants) {
this.maxParticipants = maxParticipants;
}
public Language getPresentationLanguage() {
return this.presentationLanguage;
}
public void setPresentationLanguage(Language presentationLanguage) {
this.presentationLanguage = presentationLanguage;
}
public Date getDocumentUploadDate() {
return this.documentUploadDate;
}
public void setDocumentUploadDate(Date documentUploadDate) {
this.documentUploadDate = documentUploadDate;
}
public String getExtraInfo() {
return extraInfo;
}
public void setExtraInfo(String extraInfo) {
this.extraInfo = extraInfo;
}
public String getCreationReason() {
return this.creationReason;
}
public void setCreationReason(String creationReason) {
this.creationReason = creationReason;
}
public Boolean getManualParticipants() {
return manualParticipants;
}
@ -107,21 +223,83 @@ public class FinalSeminar extends LazyDeletableDomainObject {
this.manualParticipants = manualParticipants;
}
public void setStartDate(Date startDate) {
this.startDate = (Date) startDate.clone();
public FileReference getDocument() {
return this.document;
}
public void setDocument(FileReference document) {
this.document = document;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public Set<FinalSeminarActiveParticipation> getActiveParticipations() {
return Collections.unmodifiableSet(activeParticipations);
}
public void setActiveParticipations(Collection<FinalSeminarActiveParticipation> activeParticipations) {
this.activeParticipations.clear();
this.activeParticipations.addAll(activeParticipations);
}
public Set<FinalSeminarActiveParticipation> getActiveParticipations() {
return Collections.unmodifiableSet(activeParticipations);
public Set<FinalSeminarOpposition> getOppositions() {
return Collections.unmodifiableSet(oppositions);
}
public void setOppositions(Collection<FinalSeminarOpposition> oppositions) {
this.oppositions.clear();
this.oppositions.addAll(oppositions);
}
public Set<FinalSeminarRespondent> getRespondents() {
return this.respondents;
}
public void setRespondents(Set<FinalSeminarRespondent> respondents) {
this.respondents = respondents;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
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());
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
}
@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() + ")";
}
// ----------------------------------------------------------------------------------
// Other Methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof FinalSeminar;
}
public void addActiveParticipant(FinalSeminarActiveParticipation participation) {
@ -132,25 +310,62 @@ public class FinalSeminar extends LazyDeletableDomainObject {
this.activeParticipations.remove(participation);
}
public void setOppositions(Collection<FinalSeminarOpposition> oppositions) {
this.oppositions.clear();
this.oppositions.addAll(oppositions);
public void removeActiveParticipant(User user) {
activeParticipations.removeIf(next -> next.getUser().equals(user));
}
public Set<FinalSeminarOpposition> getOppositions() {
return Collections.unmodifiableSet(oppositions);
public Set<User> getActiveParticipants(){
Set<User> activeParticipants = new HashSet<>();
for (FinalSeminarActiveParticipation fsap : activeParticipations){
activeParticipants.add(fsap.getUser());
}
return activeParticipants;
}
public Collection<User> getNotGradedActiveParticipations() {
return getNotGradedParticipations(activeParticipations);
}
public void addOpposition(FinalSeminarOpposition opposition) {
this.oppositions.add(opposition);
}
public void removeOpposition(FinalSeminarOpposition opposition) {
this.oppositions.remove(opposition);
}
public Set<User> getOpponents(){
Set<User> opponents = new HashSet<>();
for (FinalSeminarOpposition fso : oppositions){
opponents.add(fso.getUser());
}
return opponents;
}
public Collection<User> getNotGradedOpponents() {
return getNotGradedParticipations(oppositions);
}
public Collection<User> getNotGradedRespondents() {
return getNotGradedParticipations(respondents);
}
private Collection<User> getNotGradedParticipations(Set<? extends FinalSeminarParticipation> participations) {
List<User> result = new ArrayList<>();
for (FinalSeminarParticipation participation : participations) {
if(participation.getGrade() == null) {
result.add(participation.getUser());
}
}
return result;
}
public int getMinOpponents() {
return project.getMinOpponentsOnFinalSeminar();
return getProject().getMinOpponentsOnFinalSeminar();
}
public int getMinActiveParticipants() {
return project.getMinFinalSeminarActiveParticipation();
return getProject().getMinFinalSeminarActiveParticipation();
}
public List<Member> getMembers() {
@ -172,177 +387,10 @@ public class FinalSeminar extends LazyDeletableDomainObject {
}
public ProjectType getProjectType() {
return project.getProjectType();
return getProject().getProjectType();
}
public String getProjectTitle() {
return project.getTitle();
return getProject().getTitle();
}
public void setCancelled(boolean cancelled) {
setDeleted(cancelled);
}
public boolean isCancelled() {
return isDeleted();
}
public void removeOpposition(FinalSeminarOpposition opposition) {
this.oppositions.remove(opposition);
}
public Collection<User> getNotGradedOpponents() {
return getNotGradedParticipations(oppositions);
}
public Collection<User> getNotGradedActiveParticipations() {
return getNotGradedParticipations(activeParticipations);
}
public Collection<User> getNotGradedRespondents() {
return getNotGradedParticipations(respondents);
}
private Collection<User> getNotGradedParticipations(Set<? extends FinalSeminarParticipation> participations) {
List<User> result = new ArrayList<>();
for (FinalSeminarParticipation participation : participations) {
if(participation.getGrade() == null) {
result.add(participation.getUser());
}
}
return result;
}
public Set<User> getOpponents(){
Set<User> opponents = new HashSet<>();
for (FinalSeminarOpposition fso : oppositions){
opponents.add(fso.getUser());
}
return opponents;
}
public Set<User> getActiveParticipants(){
Set<User> activeParticipants = new HashSet<>();
for (FinalSeminarActiveParticipation fsap : activeParticipations){
activeParticipants.add(fsap.getUser());
}
return activeParticipants;
}
public void removeActiveParticipant(User user) {
activeParticipations.removeIf(next -> next.getUser().equals(user));
}
@Override
public Long getId() {
return this.id;
}
public Date getStartDate() {
return this.startDate;
}
public String getRoom() {
return this.room;
}
public Set<FinalSeminarRespondent> getRespondents() {
return this.respondents;
}
public FileReference getDocument() {
return this.document;
}
public Date getDocumentUploadDate() {
return this.documentUploadDate;
}
public Language getPresentationLanguage() {
return this.presentationLanguage;
}
public int getMaxOpponents() {
return this.maxOpponents;
}
public int getMaxParticipants() {
return this.maxParticipants;
}
public void setId(Long id) {
this.id = id;
}
public void setProject(Project project) {
this.project = project;
}
public void setRoom(String room) {
this.room = room;
}
public void setRespondents(Set<FinalSeminarRespondent> respondents) {
this.respondents = respondents;
}
public void setDocument(FileReference document) {
this.document = document;
}
public void setDocumentUploadDate(Date documentUploadDate) {
this.documentUploadDate = documentUploadDate;
}
public void setPresentationLanguage(Language presentationLanguage) {
this.presentationLanguage = presentationLanguage;
}
public void setMaxOpponents(int maxOpponents) {
this.maxOpponents = maxOpponents;
}
public void setMaxParticipants(int maxParticipants) {
this.maxParticipants = maxParticipants;
}
public void setCreationReason(String creationReason) {
this.creationReason = creationReason;
}
public String getExtraInfo() {
return extraInfo;
}
public void setExtraInfo(String extraInfo) {
this.extraInfo = extraInfo;
}
@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() + ")";
}
@Override
public boolean equals(final Object o) {
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());
}
protected boolean canEqual(final Object other) {
return other instanceof FinalSeminar;
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
}
public String getCreationReason() {
return this.creationReason;
}
}
}

@ -1,5 +1,6 @@
package se.su.dsv.scipro.finalseminar;
import jakarta.persistence.JoinColumn;
import se.su.dsv.scipro.project.Project;
import jakarta.persistence.Cacheable;
@ -9,13 +10,20 @@ import jakarta.persistence.Table;
import java.util.Objects;
@Entity
@Cacheable(true)
@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.
// ----------------------------------------------------------------------------------
@ManyToOne(optional = false)
@JoinColumn(name = "project_id", referencedColumnName = "id")
private Project project;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
public Project getProject() {
return this.project;
}
@ -24,6 +32,9 @@ public class FinalSeminarActiveParticipation extends FinalSeminarParticipation {
this.project = project;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -34,13 +45,16 @@ public class FinalSeminarActiveParticipation extends FinalSeminarParticipation {
&& Objects.equals(this.project, other.project);
}
@Override
protected boolean canEqual(final Object other) {
return other instanceof FinalSeminarActiveParticipation;
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), this.getProject());
}
// ----------------------------------------------------------------------------------
// Other methods
// ----------------------------------------------------------------------------------
@Override
protected boolean canEqual(final Object other) {
return other instanceof FinalSeminarActiveParticipation;
}
}

@ -13,73 +13,90 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import java.util.*;
import java.util.Objects;
@Entity
@Table(name="final_seminar_opposition")
public class FinalSeminarOpposition extends FinalSeminarParticipation {
public static final int FEEDBACK_LENGTH = 2000;
@ManyToOne(optional = false)
private Project project;
@OneToOne
@JoinColumn(name = "opponent_report_reference_id")
private FileReference opponentReport;
@OneToOne(optional = true, orphanRemoval = true, cascade = CascadeType.ALL, mappedBy = "finalSeminarOpposition")
private OppositionReport oppositionReport;
private static final int FEEDBACK_LENGTH = 2000;
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Basic
@Column(name = "points")
private Integer points;
@Basic
@Column(length = FEEDBACK_LENGTH)
@Column(name = "feedback", length = FEEDBACK_LENGTH)
private String feedback;
public ProjectType getProjectType() {
return getFinalSeminar().getProject().getProjectType();
}
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (final_seminar_opposition) referencing
// other tables.
// ----------------------------------------------------------------------------------
@OneToOne
@JoinColumn(name = "opponent_report_file_reference_id", referencedColumnName = "id")
private FileReference opponentReport;
public void setProject(final Project project) {
this.project = project;
}
@ManyToOne(optional = false)
@JoinColumn(name = "project_id", referencedColumnName = "id")
private Project project;
public Project getProject() {
return this.project;
}
public FileReference getOpponentReport() {
return this.opponentReport;
}
public OppositionReport getOppositionReport() {
return this.oppositionReport;
}
// ----------------------------------------------------------------------------------
// JPA-mappings of other tables referencing to this table (final_seminar_opposition)
// ----------------------------------------------------------------------------------
@OneToOne(optional = true, orphanRemoval = true, cascade = CascadeType.ALL,
mappedBy = "finalSeminarOpposition")
private OppositionReport oppositionReport;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
public Integer getPoints() {
return this.points;
}
public String getFeedback() {
return this.feedback;
}
public void setOpponentReport(FileReference opponentReport) {
this.opponentReport = opponentReport;
}
public void setOppositionReport(OppositionReport oppositionReport) {
this.oppositionReport = oppositionReport;
}
public void setPoints(Integer points) {
this.points = points;
}
public String getFeedback() {
return this.feedback;
}
public void setFeedback(String feedback) {
this.feedback = feedback;
}
public FileReference getOpponentReport() {
return this.opponentReport;
}
public void setOpponentReport(FileReference opponentReport) {
this.opponentReport = opponentReport;
}
public Project getProject() {
return this.project;
}
public void setProject(final Project project) {
this.project = project;
}
public OppositionReport getOppositionReport() {
return this.oppositionReport;
}
public void setOppositionReport(OppositionReport oppositionReport) {
this.oppositionReport = oppositionReport;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -90,13 +107,20 @@ public class FinalSeminarOpposition extends FinalSeminarParticipation {
&& Objects.equals(this.getProject(), other.getProject());
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), this.getProject());
}
// ----------------------------------------------------------------------------------
// Other Methods
// ----------------------------------------------------------------------------------
@Override
protected boolean canEqual(final Object other) {
return other instanceof FinalSeminarOpposition;
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), this.getProject());
public ProjectType getProjectType() {
return getFinalSeminar().getProject().getProjectType();
}
}

@ -1,6 +1,6 @@
package se.su.dsv.scipro.finalseminar;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.system.ProjectType;

@ -1,64 +1,66 @@
package se.su.dsv.scipro.finalseminar;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
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.ManyToOne;
import jakarta.persistence.MappedSuperclass;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.User;
import jakarta.persistence.*;
import java.util.Objects;
@MappedSuperclass
public abstract class FinalSeminarParticipation extends DomainObject {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(optional = false)
private User user;
@Basic
@Enumerated(EnumType.STRING)
@Column(name = "grade")
private FinalSeminarGrade grade = null;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in tables whose entity class inherits from
// FinalSeminarParticipation class (such as final_seminar_active_participation,
// final_seminar_opposition, final_seminar_respondent) referencing other tables.
// ----------------------------------------------------------------------------------
@ManyToOne(optional = false)
@JoinColumn(name = "final_seminar_id", referencedColumnName = "id")
private FinalSeminar finalSeminar;
@Enumerated(EnumType.STRING)
private FinalSeminarGrade grade = null;
@ManyToOne(optional = false)
@JoinColumn(name = "user_id", referencedColumnName = "id")
private User user;
// ----------------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------------
protected FinalSeminarParticipation() {
}
protected FinalSeminarParticipation(User user, FinalSeminar finalSeminar) {
this.user = user;
this.finalSeminar = finalSeminar;
}
protected FinalSeminarParticipation() {
}
public boolean isApproved() {
return grade == FinalSeminarGrade.APPROVED;
}
public boolean hasGrade() {
return (grade != null);
}
public void setUser(final User user) {
this.user = user;
}
public void setFinalSeminar(final FinalSeminar finalSeminar) {
this.finalSeminar = finalSeminar;
}
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
@Override
public Long getId() {
return this.id;
}
public User getUser() {
return this.user;
}
public FinalSeminar getFinalSeminar() {
return this.finalSeminar;
}
public FinalSeminarGrade getGrade() {
return this.grade;
}
@ -67,6 +69,29 @@ public abstract class FinalSeminarParticipation extends DomainObject {
this.grade = grade;
}
public boolean hasGrade() {
return (grade != null);
}
public FinalSeminar getFinalSeminar() {
return this.finalSeminar;
}
public void setFinalSeminar(final FinalSeminar finalSeminar) {
this.finalSeminar = finalSeminar;
}
public User getUser() {
return this.user;
}
public void setUser(final User user) {
this.user = user;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -77,12 +102,20 @@ public abstract class FinalSeminarParticipation extends DomainObject {
&& Objects.equals(this.getFinalSeminar(), other.getFinalSeminar());
}
protected boolean canEqual(final Object other) {
return other instanceof FinalSeminarParticipation;
}
@Override
public int hashCode() {
return Objects.hash(this.getUser(), this.getFinalSeminar());
}
// ----------------------------------------------------------------------------------
// Other methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof FinalSeminarParticipation;
}
public boolean isApproved() {
return grade == FinalSeminarGrade.APPROVED;
}
}

@ -1,6 +1,6 @@
package se.su.dsv.scipro.finalseminar;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.AbstractRepository;
@ -9,7 +9,7 @@ import jakarta.inject.Provider;
public class FinalSeminarRepositoryImpl extends AbstractRepository implements FinalSeminarRepository {
@Inject
protected FinalSeminarRepositoryImpl(Provider<EntityManager> em) {
public FinalSeminarRepositoryImpl(Provider<EntityManager> em) {
super(em);
}

@ -8,17 +8,17 @@ import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
@Cacheable(true)
@Table(name = "final_seminar_respondent")
@Cacheable(true)
public class FinalSeminarRespondent extends FinalSeminarParticipation {
protected FinalSeminarRespondent() {
}
public FinalSeminarRespondent(User student, FinalSeminar finalSeminar) {
super(student, finalSeminar);
}
protected FinalSeminarRespondent() {
}
public Project getProject() {
return getFinalSeminar().getProject();
}

@ -1,5 +1,6 @@
package se.su.dsv.scipro.finalseminar;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.User;
@ -33,6 +34,7 @@ public class FinalSeminarRespondentServiceImpl extends AbstractServiceImpl<Final
}
@Override
@Transactional
public List<FinalSeminarRespondent> findOrCreate(FinalSeminar finalSeminar) {
if(finalSeminar.getId() == null) {
return new ArrayList<>();

@ -1,7 +1,7 @@
package se.su.dsv.scipro.finalseminar;
import com.google.common.eventbus.EventBus;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.BooleanExpression;
import jakarta.persistence.EntityManager;

@ -7,6 +7,7 @@ import java.util.Objects;
@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;
@ -22,25 +23,26 @@ public class FinalSeminarSettings extends DomainObject {
this.id = id;
}
@Basic(optional = false)
@Column(name = "days_ahead_to_create", nullable = false)
private int daysAheadToCreate;
@Basic(optional = false)
@Column(name = "days_ahead_to_register_participation", nullable = false)
private int daysAheadToRegisterParticipation = DEFAULT_DAYS_AHEAD_TO_REGISTER_PARTICIPATION;
@Basic(optional = false)
@Column(name = "days_ahead_to_register_opposition", nullable = false)
private int daysAheadToRegisterOpposition = DEFAULT_DAYS_AHEAD_TO_REGISTER_OPPOSITION;
@Basic(optional = false)
@Column(name = "days_ahead_to_upload_thesis", nullable = false)
private int daysAheadToUploadThesis = DEFAULT_DAYS_AHEAD_TO_UPLOAD_THESIS;
@Basic(optional = false)
@Column(name = "thesis_must_be_pdf", nullable = false)
private boolean thesisMustBePDF = false;
@Basic(optional = true)
@Column(name = "evaluation_url", nullable = true)
private String evaluationURL;
@Basic(optional = false)
@Column(name = "opposition_priority_days", nullable = false)
private int oppositionPriorityDays;
public boolean getThesisMustBePDF() {

@ -1,6 +1,6 @@
package se.su.dsv.scipro.finalseminar;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;

@ -1,7 +1,7 @@
package se.su.dsv.scipro.finalseminar;
import com.google.common.eventbus.EventBus;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.su.dsv.scipro.file.*;

@ -21,50 +21,67 @@ import jakarta.persistence.Table;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.Date;
import java.util.Objects;
@Entity
@Table
@Table(name = "final_thesis")
public class FinalThesis extends DomainObject {
public enum Status {
APPROVED, REJECTED, NO_DECISION
}
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(optional = false)
@JoinColumn(name = "document_reference_id")
private FileReference document;
@Basic
@Column(name = "title_sv")
private String swedishTitle;
@ManyToOne(optional = true)
@JoinColumn(name = "text_matching_document_reference_id")
private FileReference textMatchingDocument;
@Basic
@Column(name = "title_en")
private String englishTitle;
@Basic
@Column(name = "status")
@Enumerated(EnumType.STRING)
private Status status = Status.NO_DECISION;
@Basic
@Column(name = "date_approved")
private Date dateApproved;
@Basic
@Column(name = "date_rejected")
private Date dateRejected;
@Basic
@Column(name = "rejection_comment")
private String rejectionComment;
@Basic
@Column(name = "text_matching_analysis")
private String textMatchingAnalysis;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (final_thesis) referencing other tables.
// ----------------------------------------------------------------------------------
@ManyToOne(optional = true)
@JoinColumn(name = "text_matching_document_reference_id", referencedColumnName = "id")
private FileReference textMatchingDocument;
@ManyToOne(optional = false)
@JoinColumn(name = "project_id")
@JoinColumn(name = "document_reference_id", referencedColumnName = "id")
private FileReference document;
@ManyToOne(optional = false)
@JoinColumn(name = "project_id", referencedColumnName = "id")
private Project project;
@Enumerated(EnumType.STRING)
private Status status = Status.NO_DECISION;
private Date dateApproved;
private Date dateRejected;
private String englishTitle;
private String swedishTitle;
@Column(name = "rejection_comment")
private String rejectionComment;
// ----------------------------------------------------------------------------------
// JPA lifecycle method
// ----------------------------------------------------------------------------------
@PrePersist
@PreUpdate
void cleanTitle() {
@ -72,6 +89,126 @@ public class FinalThesis extends DomainObject {
this.swedishTitle = clean(this.swedishTitle);
}
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
@Override
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getEnglishTitle() {
return this.englishTitle;
}
public void setEnglishTitle(String englishTitle) {
this.englishTitle = englishTitle;
}
public String getSwedishTitle() {
return this.swedishTitle;
}
public void setSwedishTitle(String swedishTitle) {
this.swedishTitle = swedishTitle;
}
public Status getStatus() {
return this.status;
}
public void setStatus(Status status) {
this.status = status;
}
public Date getDateApproved() {
return dateApproved;
}
public void setDateApproved(Date dateApproved) {
this.dateApproved = dateApproved;
}
public Date getDateRejected() {
return dateRejected;
}
public void setDateRejected(Date dateRejected) {
this.dateRejected = dateRejected;
}
public String getRejectionComment() {
return rejectionComment;
}
public void setRejectionComment(String rejectionComment) {
this.rejectionComment = rejectionComment;
}
public String getTextMatchingAnalysis() {
return textMatchingAnalysis;
}
public void setTextMatchingAnalysis(String textMatchingAnalysis) {
this.textMatchingAnalysis = textMatchingAnalysis;
}
public FileReference getTextMatchingDocument() {
return this.textMatchingDocument;
}
public void setTextMatchingDocument(FileReference textMatchingDocument) {
this.textMatchingDocument = textMatchingDocument;
}
public FileReference getDocument() {
return this.document;
}
public void setDocument(FileReference fileDescription) {
this.document = fileDescription;
}
public Project getProject() {
return this.project;
}
public void setProject(Project project) {
this.project = project;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof FinalThesis)) return false;
final FinalThesis other = (FinalThesis) o;
return other.canEqual(this)
&& Objects.equals(this.getDocument(), other.getDocument())
&& Objects.equals(this.getProject(), other.getProject());
}
@Override
public int hashCode() {
return Objects.hash(this.getDocument(), this.getProject());
}
@Override
public String toString() {
return "FinalThesis(id=" + this.getId() + ", fileDescription=" + this.getDocument() + ", textMatchingDocument=" + this.getTextMatchingDocument() + ", project=" + this.getProject() + ", status=" + this.getStatus() + ", dateApproved=" + this.getDateApproved() + ", dateRejected=" + this.getDateRejected() + ", englishTitle=" + this.getEnglishTitle() + ", swedishTitle=" + this.getSwedishTitle() + ")";
}
// ----------------------------------------------------------------------------------
// Other methods
// ----------------------------------------------------------------------------------
private String clean(String str) {
if (str == null) {
return null;
@ -83,125 +220,23 @@ public class FinalThesis extends DomainObject {
.trim();
}
@Override
public Long getId() {
return this.id;
}
public FileReference getDocument() {
return this.document;
}
public FileReference getTextMatchingDocument() {
return this.textMatchingDocument;
}
public Project getProject() {
return this.project;
}
public Status getStatus() {
return this.status;
}
public String getEnglishTitle() {
return this.englishTitle;
}
public String getSwedishTitle() {
return this.swedishTitle;
}
public void setId(Long id) {
this.id = id;
}
public void setDocument(FileReference fileDescription) {
this.document = fileDescription;
}
public void setTextMatchingDocument(FileReference textMatchingDocument) {
this.textMatchingDocument = textMatchingDocument;
}
public void setProject(Project project) {
this.project = project;
}
public void setStatus(Status status) {
this.status = status;
}
public void setDateApproved(Date dateApproved) {
this.dateApproved = dateApproved;
}
public void setDateRejected(Date dateRejected) {
this.dateRejected = dateRejected;
}
public void setEnglishTitle(String englishTitle) {
this.englishTitle = englishTitle;
}
public void setSwedishTitle(String swedishTitle) {
this.swedishTitle = swedishTitle;
}
public String getTextMatchingAnalysis() {
return textMatchingAnalysis;
}
public void setTextMatchingAnalysis(String textMatchingAnalysis) {
this.textMatchingAnalysis = textMatchingAnalysis;
}
public String getRejectionComment() {
return rejectionComment;
}
public void setRejectionComment(String rejectionComment) {
this.rejectionComment = rejectionComment;
}
@Override
public String toString() {
return "FinalThesis(id=" + this.getId() + ", fileDescription=" + this.getDocument() + ", textMatchingDocument=" + this.getTextMatchingDocument() + ", project=" + this.getProject() + ", status=" + this.getStatus() + ", dateApproved=" + this.getDateApproved() + ", dateRejected=" + this.getDateRejected() + ", englishTitle=" + this.getEnglishTitle() + ", swedishTitle=" + this.getSwedishTitle() + ")";
}
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof FinalThesis)) return false;
final FinalThesis other = (FinalThesis) o;
return other.canEqual(this)
&& Objects.equals(this.getDocument(), other.getDocument())
&& Objects.equals(this.getProject(), other.getProject());
}
protected boolean canEqual(final Object other) {
return other instanceof FinalThesis;
}
@Override
public int hashCode() {
return Objects.hash(this.getDocument(), this.getProject());
}
public boolean isRejected() {
return getStatus() == Status.REJECTED;
}
public Date getDateRejected() {
return dateRejected;
}
public Date getDateApproved() {
return dateApproved;
}
public LocalDate getUploadDate() {
Instant instant = document.getFileDescription().getDateCreated().toInstant();
return instant.atZone(ZoneId.systemDefault()).toLocalDate();
}
public boolean isRejected() {
return getStatus() == Status.REJECTED;
}
// ----------------------------------------------------------------------------------
// Nested types
// ----------------------------------------------------------------------------------
public enum Status {
APPROVED, REJECTED, NO_DECISION
}
}

@ -1,7 +1,7 @@
package se.su.dsv.scipro.finalthesis;
import com.google.common.eventbus.EventBus;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
import jakarta.persistence.EntityManager;
@ -56,6 +56,7 @@ public class FinalThesisServiceImpl extends AbstractServiceImpl<FinalThesis, Lon
}
@Override
@Transactional
public FinalThesis upload(ProjectFileUpload fileUpload, String englishTitle, String swedishTitle) {
ProjectFile fileDescription = storeFinalThesisFile(fileUpload);
final FileReference reference = fileService.createReference(fileDescription.getFileDescription());
@ -133,6 +134,7 @@ public class FinalThesisServiceImpl extends AbstractServiceImpl<FinalThesis, Lon
}
@Override
@Transactional
public void removeApproval(Project project) {
setStatus(project, FinalThesis.Status.NO_DECISION);
}

@ -1,11 +0,0 @@
package se.su.dsv.scipro.firstmeeting;
import com.google.inject.AbstractModule;
import se.su.dsv.scipro.firstmeeting.FirstMeetingReminderWorker.FirstMeetingReminderWorkerSchedule;
public class FirstMeetingModule extends AbstractModule {
@Override
public void configure() {
bind(FirstMeetingReminderWorkerSchedule.class).asEagerSingleton();
}
}

@ -1,5 +1,6 @@
package se.su.dsv.scipro.firstmeeting;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.activityplan.Activity;
import se.su.dsv.scipro.activityplan.ActivityPlanFacade;
import se.su.dsv.scipro.project.Project;
@ -26,6 +27,7 @@ public class FirstMeetingServiceImpl extends AbstractServiceImpl<ProjectFirstMee
}
@Override
@Transactional
public ProjectFirstMeeting schedule(final Project project, final Date date, final String room, final String description) {
final Optional<ProjectFirstMeeting> optFirstMeeting = findByProject(project);
final ProjectFirstMeeting firstMeeting = optFirstMeeting

@ -1,37 +1,58 @@
package se.su.dsv.scipro.firstmeeting;
import com.querydsl.core.annotations.QueryInit;
import jakarta.persistence.Basic;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import se.su.dsv.scipro.activityplan.Activity;
import se.su.dsv.scipro.system.DomainObject;
import jakarta.persistence.*;
import java.util.Date;
@Entity
@Table(name = "project_first_meeting")
public final class ProjectFirstMeeting extends DomainObject {
// ----------------------------------------------------------------------------------
// basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@QueryInit("activityPlan.project")
@OneToOne(optional = false, cascade = CascadeType.ALL)
private Activity activity;
@Basic(optional = false)
@Column(name = "room")
private String room;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (project_first_meeting) referencing
// other tables.
// ----------------------------------------------------------------------------------
@OneToOne(optional = false, cascade = CascadeType.ALL)
@JoinColumn(name = "activity_id", referencedColumnName = "id")
@QueryInit("activityPlan.project")
private Activity activity;
// ----------------------------------------------------------------------------------
// constructor
// ----------------------------------------------------------------------------------
protected ProjectFirstMeeting() {}
// ----------------------------------------------------------------------------------
// getters and setters
// ----------------------------------------------------------------------------------
@Override
public Long getId() {
return id;
}
public Date getDate() {
return activity.getDate();
}
public String getRoom() {
return room;
}
@ -40,10 +61,6 @@ public final class ProjectFirstMeeting extends DomainObject {
this.room = room;
}
public String getDescription() {
return activity.getDescription();
}
Activity getActivity() {
return activity;
}
@ -51,4 +68,15 @@ public final class ProjectFirstMeeting extends DomainObject {
void setActivity(Activity activity) {
this.activity = activity;
}
// ----------------------------------------------------------------------------------
// other methods
// ----------------------------------------------------------------------------------
public Date getDate() {
return activity.getDate();
}
public String getDescription() {
return activity.getDescription();
}
}

@ -1,7 +1,7 @@
package se.su.dsv.scipro.forum;
import com.google.common.eventbus.EventBus;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.file.FileService;
import se.su.dsv.scipro.forum.dataobjects.ForumPost;

@ -1,26 +0,0 @@
package se.su.dsv.scipro.forum;
import com.google.inject.PrivateModule;
public class ForumModule extends PrivateModule {
@Override
protected void configure() {
bind(AbstractThreadRepository.class).to(AbstractThreadRepositoryImpl.class);
bind(ForumPostReadStateRepository.class).to(ForumPostReadStateRepositoryImpl.class);
bind(ForumPostRepository.class).to(ForumPostRepositoryImpl.class);
bind(ProjectThreadRepository.class).to(ProjectThreadRepositoryImpl.class);
bind(GroupThreadRepository.class).to(GroupThreadRepositoryImpl.class);
expose(ProjectThreadRepository.class);
expose(GroupThreadRepository.class);
bind(ProjectForumService.class).to(ProjectForumServiceImpl.class);
bind(GroupForumService.class).to(GroupForumServiceImpl.class);
expose(ProjectForumService.class);
expose(GroupForumService.class);
bind(BasicForumService.class).to(BasicForumServiceImpl.class);
expose(BasicForumService.class);
}
}

@ -1,6 +1,6 @@
package se.su.dsv.scipro.forum;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.forum.dataobjects.ForumPost;

@ -1,6 +1,6 @@
package se.su.dsv.scipro.forum;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import jakarta.persistence.LockModeType;
import se.su.dsv.scipro.forum.dataobjects.ForumPost;
import se.su.dsv.scipro.forum.dataobjects.ForumPostReadState;

@ -1,6 +1,6 @@
package se.su.dsv.scipro.forum;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.forum.dataobjects.ForumPost;

@ -1,7 +1,7 @@
package se.su.dsv.scipro.forum;
import com.google.common.eventbus.EventBus;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.forum.dataobjects.ForumPost;
import se.su.dsv.scipro.forum.dataobjects.ForumThread;
import se.su.dsv.scipro.forum.dataobjects.GroupThread;

@ -1,6 +1,6 @@
package se.su.dsv.scipro.forum;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.forum.dataobjects.GroupThread;

@ -1,7 +1,7 @@
package se.su.dsv.scipro.forum;
import com.google.common.eventbus.EventBus;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.file.FileSource;
import se.su.dsv.scipro.file.ProjectFileService;
import se.su.dsv.scipro.forum.dataobjects.ForumPost;

@ -1,6 +1,6 @@
package se.su.dsv.scipro.forum;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.forum.dataobjects.ProjectThread;

@ -1,5 +1,6 @@
package se.su.dsv.scipro.forum.dataobjects;
import jakarta.persistence.Basic;
import jakarta.persistence.GenerationType;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.system.LazyDeletableDomainObject;
@ -15,54 +16,51 @@ import jakarta.persistence.Lob;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.util.*;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "forum_post")
public class ForumPost extends LazyDeletableDomainObject {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Lob
@Basic
@Column(name = "content", nullable = false)
@Lob
private String content;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (forum_post) referencing other
// tables.
// ----------------------------------------------------------------------------------
@ManyToOne
@JoinColumn(name = "user", nullable = true)
private User postedBy;
@ManyToOne
@JoinColumn(name = "thread", nullable = false)
@JoinColumn(name = "thread_id", nullable = false)
private ForumThread forumThread;
@ManyToOne
@JoinColumn(name = "user_id", nullable = true)
private User postedBy;
// ----------------------------------------------------------------------------------
// JPA-mappings of other tables referencing to this table "forum_post"
// ----------------------------------------------------------------------------------
@OneToMany(orphanRemoval = true)
@JoinTable(name = "forum_post_file_description",
joinColumns = {@JoinColumn(name = "forum_post_id")},
@JoinTable(name = "forum_post_file_reference",
joinColumns = {@JoinColumn(name = "forum_post_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "file_reference_id")})
private Set<FileReference> attachments = new HashSet<>();
public String getSubject() {
return forumThread.getSubject();
}
public Set<FileReference> getAttachments() {
return attachments;
}
public User getPostedBy() {
return postedBy;
}
public String getContent() {
return content;
}
public ForumThread getForumThread() {
return forumThread;
}
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
@Override
public Long getId() {
return this.id;
@ -72,27 +70,41 @@ public class ForumPost extends LazyDeletableDomainObject {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public void setPostedBy(User postedBy) {
this.postedBy = postedBy;
public ForumThread getForumThread() {
return forumThread;
}
public void setForumThread(ForumThread forumThread) {
this.forumThread = forumThread;
}
public User getPostedBy() {
return postedBy;
}
public void setPostedBy(User postedBy) {
this.postedBy = postedBy;
}
public Set<FileReference> getAttachments() {
return attachments;
}
public void setAttachments(Set<FileReference> attachments) {
this.attachments = attachments;
}
@Override
public String toString() {
return "ForumPost(id=" + this.getId() + ", content=" + this.getContent() + ", postedBy=" + this.getPostedBy() + ", forumThread=" + this.getForumThread() + ", attachments=" + this.getAttachments() + ")";
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -106,10 +118,6 @@ public class ForumPost extends LazyDeletableDomainObject {
&& Objects.equals(this.getAttachments(), other.getAttachments());
}
protected boolean canEqual(final Object other) {
return other instanceof ForumPost;
}
@Override
public int hashCode() {
return Objects.hash(
@ -119,4 +127,22 @@ public class ForumPost extends LazyDeletableDomainObject {
this.getForumThread(),
this.getAttachments());
}
@Override
public String toString() {
return "ForumPost(id=" + this.getId() + ", content=" + this.getContent() +
", postedBy=" + this.getPostedBy() + ", forumThread=" + this.getForumThread() +
", attachments=" + this.getAttachments() + ")";
}
// ----------------------------------------------------------------------------------
// Other methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof ForumPost;
}
public String getSubject() {
return forumThread.getSubject();
}
}

@ -1,14 +1,21 @@
package se.su.dsv.scipro.forum.dataobjects;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import se.su.dsv.scipro.system.User;
import jakarta.persistence.*;
import java.io.Serializable;
@Entity
@Table(name = "forum_post_read")
@Table(name = "forum_post_read_state")
public class ForumPostReadState implements Serializable {
// ----------------------------------------------------------------------------------
// Basic and embedded JPA-mappings
// ----------------------------------------------------------------------------------
@EmbeddedId
private ForumPostReadStateId id;
@ -16,6 +23,9 @@ public class ForumPostReadState implements Serializable {
@Column(name = "`read`", nullable = false)
private boolean read = false;
// ----------------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------------
public ForumPostReadState() {
}
@ -23,6 +33,9 @@ public class ForumPostReadState implements Serializable {
id = new ForumPostReadStateId(user, post);
}
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
public ForumPostReadStateId getId() {
return id;
}
@ -39,4 +52,3 @@ public class ForumPostReadState implements Serializable {
this.read = read;
}
}

@ -11,11 +11,11 @@ import java.util.Objects;
@Embeddable
public class ForumPostReadStateId implements Serializable {
@ManyToOne
@JoinColumn(name = "user", nullable = false)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@ManyToOne
@JoinColumn(name = "post", nullable = false)
@JoinColumn(name = "forum_post_id", nullable = false)
private ForumPost post;
public ForumPostReadStateId() {

@ -1,9 +1,21 @@
package se.su.dsv.scipro.forum.dataobjects;
import jakarta.persistence.Basic;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType;
import jakarta.persistence.OneToMany;
import jakarta.persistence.PostLoad;
import jakarta.persistence.Table;
import se.su.dsv.scipro.system.LazyDeletableDomainObject;
import se.su.dsv.scipro.system.User;
import jakarta.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -13,17 +25,88 @@ import java.util.Objects;
@Inheritance(strategy = InheritanceType.JOINED)
public class ForumThread extends LazyDeletableDomainObject {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "forumThread", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<ForumPost> posts = new ArrayList<>();
@Basic
@Column(name = "subject", nullable = false)
private String subject;
// ----------------------------------------------------------------------------------
// JPA-mappings of other tables referencing to this table "thread"
// ----------------------------------------------------------------------------------
@OneToMany(mappedBy = "forumThread", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<ForumPost> posts = new ArrayList<>();
// ----------------------------------------------------------------------------------
// JPA-lifecycle method
// ----------------------------------------------------------------------------------
@PostLoad
void lazyDeletion() {
posts.removeIf(LazyDeletableDomainObject::isDeleted);
}
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
@Override
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public List<ForumPost> getPosts() {
return this.posts;
}
public void setPosts(List<ForumPost> posts) {
this.posts = posts;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof ForumThread)) return false;
final ForumThread other = (ForumThread) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
}
@Override
public String toString() {
return "ForumThread(id=" + this.getId() + ", subject=" + this.getSubject() + ")";
}
// ----------------------------------------------------------------------------------
// Other methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof ForumThread;
}
public void addPost(ForumPost post) {
posts.add(post);
}
@ -32,15 +115,6 @@ public class ForumThread extends LazyDeletableDomainObject {
return posts.size();
}
@PostLoad
void lazyDeletion() {
posts.removeIf(LazyDeletableDomainObject::isDeleted);
}
public String getSubject() {
return subject;
}
public User getCreatedBy(){
return getPosts().get(0).getPostedBy();
}
@ -53,48 +127,4 @@ public class ForumThread extends LazyDeletableDomainObject {
}
return false;
}
@Override
public Long getId() {
return this.id;
}
public List<ForumPost> getPosts() {
return this.posts;
}
public void setId(Long id) {
this.id = id;
}
public void setPosts(List<ForumPost> posts) {
this.posts = posts;
}
public void setSubject(String subject) {
this.subject = subject;
}
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof ForumThread)) return false;
final ForumThread other = (ForumThread) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
}
protected boolean canEqual(final Object other) {
return other instanceof ForumThread;
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
}
@Override
public String toString() {
return "ForumThread(id=" + this.getId() + ", subject=" + this.getSubject() + ")";
}
}

@ -1,49 +1,70 @@
package se.su.dsv.scipro.forum.dataobjects;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
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 jakarta.persistence.Table;
import se.su.dsv.scipro.group.Group;
import jakarta.persistence.*;
import java.io.Serializable;
import java.util.Objects;
@Entity
@Table(name = "group_thread")
@Table(name = "project_group_thread")
public class GroupThread implements Serializable {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (project_group_thread) referencing other
// tables.
// ----------------------------------------------------------------------------------
@ManyToOne
@JoinColumn(name = "group_id", nullable = false)
@JoinColumn(name = "project_group_id", referencedColumnName = "id", nullable = false)
private Group group;
@OneToOne(cascade = CascadeType.ALL, optional = false)
@JoinColumn(name = "thread_id")
@JoinColumn(name = "thread_id", referencedColumnName = "id")
private ForumThread forumThread;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
public Long getId() { return id; }
public Group getGroup() {
return group;
}
public ForumThread getForumThread() {
return forumThread;
}
public void setId(Long id) {
this.id = id;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public ForumThread getForumThread() {
return forumThread;
}
public void setForumThread(ForumThread forumThread) {
this.forumThread = forumThread;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -55,10 +76,6 @@ public class GroupThread implements Serializable {
&& Objects.equals(this.getForumThread(), other.getForumThread());
}
protected boolean canEqual(final Object other) {
return other instanceof GroupThread;
}
@Override
public int hashCode() {
return Objects.hash(this.getId(), this.getGroup(), this.getForumThread());
@ -66,6 +83,14 @@ public class GroupThread implements Serializable {
@Override
public String toString() {
return "GroupThread(id=" + this.getId() + ", group=" + this.getGroup() + ", forumThread=" + this.getForumThread() + ")";
return "GroupThread(id=" + this.getId() + ", group=" + this.getGroup() + ", forumThread=" +
this.getForumThread() + ")";
}
// ----------------------------------------------------------------------------------
// Other methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof GroupThread;
}
}

@ -1,50 +1,70 @@
package se.su.dsv.scipro.forum.dataobjects;
import jakarta.persistence.Entity;
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 jakarta.persistence.Table;
import se.su.dsv.scipro.project.Project;
import jakarta.persistence.*;
import java.io.Serializable;
import java.util.Objects;
@Entity
@Table(name = "project_thread")
public class ProjectThread implements Serializable {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(optional = false)
@JoinColumn(name = "thread_id")
private ForumThread forumThread;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (project_thread) referencing other
// tables.
// ----------------------------------------------------------------------------------
@ManyToOne(optional = false)
@JoinColumn(name = "project_id")
@JoinColumn(name = "project_id", referencedColumnName = "id")
private Project project;
@OneToOne(optional = false)
@JoinColumn(name = "thread_id", referencedColumnName = "id")
private ForumThread forumThread;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
public Long getId() {
return id;
}
public Project getProject() {
return project;
}
public ForumThread getForumThread() {
return forumThread;
}
public void setId(Long id) {
this.id = id;
}
public void setForumThread(ForumThread forumThread) {
this.forumThread = forumThread;
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public ForumThread getForumThread() {
return forumThread;
}
public void setForumThread(ForumThread forumThread) {
this.forumThread = forumThread;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -56,10 +76,6 @@ public class ProjectThread implements Serializable {
&& Objects.equals(this.getProject(), other.getProject());
}
protected boolean canEqual(final Object other) {
return other instanceof ProjectThread;
}
@Override
public int hashCode() {
return Objects.hash(this.getId(), this.getForumThread(), this.getProject());
@ -67,6 +83,14 @@ public class ProjectThread implements Serializable {
@Override
public String toString() {
return "ProjectThread(id=" + this.getId() + ", forumThread=" + this.getForumThread() + ", project=" + this.getProject() + ")";
return "ProjectThread(id=" + this.getId() + ", forumThread=" + this.getForumThread() +
", project=" + this.getProject() + ")";
}
// ----------------------------------------------------------------------------------
// Other methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof ProjectThread;
}
}

@ -1,50 +1,69 @@
package se.su.dsv.scipro.forum.dataobjects;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import se.su.dsv.scipro.project.Project;
import jakarta.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "reviewer_thread")
public class ReviewerThread {
// ----------------------------------------------------------------------------------
// Basic JPA-mapping
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(optional = false)
@JoinColumn(name = "thread_id")
private ForumThread forumThread;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (mail_event) referencing other
// tables.
// ----------------------------------------------------------------------------------
@OneToOne
@JoinColumn(name = "project_id", unique = true)
@JoinColumn(name = "project_id", referencedColumnName = "id", unique = true)
private Project project;
@OneToOne(optional = false)
@JoinColumn(name = "thread_id", referencedColumnName = "id")
private ForumThread forumThread;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
public Long getId() {
return this.id;
}
public ForumThread getForumThread() {
return this.forumThread;
}
public Project getProject() {
return this.project;
}
public void setId(Long id) {
this.id = id;
}
public void setForumThread(ForumThread forumThread) {
this.forumThread = forumThread;
public Project getProject() {
return this.project;
}
public void setProject(Project project) {
this.project = project;
}
public ForumThread getForumThread() {
return this.forumThread;
}
public void setForumThread(ForumThread forumThread) {
this.forumThread = forumThread;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -56,10 +75,6 @@ public class ReviewerThread {
&& Objects.equals(this.getProject(), other.getProject());
}
protected boolean canEqual(final Object other) {
return other instanceof ReviewerThread;
}
@Override
public int hashCode() {
return Objects.hash(this.getId(), this.getForumThread(), this.getProject());
@ -67,6 +82,14 @@ public class ReviewerThread {
@Override
public String toString() {
return "ReviewerThread(id=" + this.getId() + ", forumThread=" + this.getForumThread() + ", project=" + this.getProject() + ")";
return "ReviewerThread(id=" + this.getId() + ", forumThread=" + this.getForumThread() +
", project=" + this.getProject() + ")";
}
// ----------------------------------------------------------------------------------
// Other methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof ReviewerThread;
}
}

@ -1,26 +1,44 @@
package se.su.dsv.scipro.forum.notifications;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapsId;
import jakarta.persistence.Table;
import se.su.dsv.scipro.forum.dataobjects.ForumPost;
import se.su.dsv.scipro.notifications.dataobject.NotificationEvent;
import jakarta.persistence.*;
import java.io.Serializable;
import java.util.Objects;
@Entity
@Table(name = "forum_notification")
class ForumNotification {
// ----------------------------------------------------------------------------------
// Embedded JPA-mapping
// ----------------------------------------------------------------------------------
@EmbeddedId
private Id id = new Id();
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (forum_notification) referencing other
// tables.
// ----------------------------------------------------------------------------------
@ManyToOne(optional = false)
@JoinColumn(name = "forum_post_id", referencedColumnName = "id")
@MapsId("forumPostId")
private ForumPost forumPost;
@ManyToOne(optional = false)
@JoinColumn(name = "notification_data_id")
@MapsId("notificationEventId")
private NotificationEvent notificationEvent;
// ----------------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------------
protected ForumNotification() { } // JPA
ForumNotification(final ForumPost forumPost, final NotificationEvent notificationEvent) {
@ -28,6 +46,9 @@ class ForumNotification {
this.notificationEvent = notificationEvent;
}
// ----------------------------------------------------------------------------------
// Properties (Getters)
// ----------------------------------------------------------------------------------
public ForumPost getForumPost() {
return forumPost;
}
@ -36,6 +57,9 @@ class ForumNotification {
return notificationEvent;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -47,10 +71,6 @@ class ForumNotification {
&& Objects.equals(this.getNotificationEvent(), other.getNotificationEvent());
}
protected boolean canEqual(final Object other) {
return other instanceof ForumNotification;
}
@Override
public int hashCode() {
return Objects.hash(this.id, this.getForumPost(), this.getNotificationEvent());
@ -58,9 +78,20 @@ class ForumNotification {
@Override
public String toString() {
return "ForumNotification(id=" + this.id + ", forumPost=" + this.getForumPost() + ", notificationEvent=" + this.getNotificationEvent() + ")";
return "ForumNotification(id=" + this.id + ", forumPost=" + this.getForumPost() +
", notificationEvent=" + this.getNotificationEvent() + ")";
}
// ----------------------------------------------------------------------------------
// Other method
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof ForumNotification;
}
// ----------------------------------------------------------------------------------
// Nested type
// ----------------------------------------------------------------------------------
@Embeddable
static class Id implements Serializable {
private Long forumPostId;
@ -103,7 +134,8 @@ class ForumNotification {
@Override
public String toString() {
return "ForumNotification.Id(forumPostId=" + this.getForumPostId() + ", notificationEventId=" + this.getNotificationEventId() + ")";
return "ForumNotification.Id(forumPostId=" + this.getForumPostId() + ", notificationEventId=" +
this.getNotificationEventId() + ")";
}
}
}

@ -2,7 +2,7 @@ package se.su.dsv.scipro.forum.notifications;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.forum.dataobjects.ForumPost;
import se.su.dsv.scipro.forum.ForumPostReadEvent;
import se.su.dsv.scipro.forum.NewGroupForumReplyEvent;

@ -1,11 +0,0 @@
package se.su.dsv.scipro.forum.notifications;
import com.google.inject.AbstractModule;
public class ForumNotificationsModule extends AbstractModule {
@Override
public void configure() {
bind(ForumNotificationRepository.class).to(ForumNotificationRepositoryImpl.class);
bind(ForumNotifications.class).asEagerSingleton();
}
}

@ -1,12 +0,0 @@
package se.su.dsv.scipro.gdpr;
import com.google.inject.PrivateModule;
public class GDPRModule extends PrivateModule {
@Override
protected void configure() {
bind(Reporter.class).to(ZipReporter.class);
expose(Reporter.class);
}
}

@ -14,81 +14,86 @@ public class GeneralSystemSettings extends DomainObject {
@Id
private Long id = null;
@Basic
@Column(name = "daisy_profile_link_base_url")
private String daisyProfileLinkBaseURL;
@Basic
@Column(name = "daisy_select_research_area_url")
private String daisySelectResearchAreaURL;
@ElementCollection
@CollectionTable(name = "general_system_settings_alarm_recipients")
@CollectionTable(name = "general_system_settings_alarm_recipient",
joinColumns = @JoinColumn(name = "general_system_settings_id", referencedColumnName = "id"))
@Column(name = "mail")
private List<String> alarmMails = new ArrayList<>();
@ElementCollection
@CollectionTable(name = "general_system_settings_supervisor_change_recipients")
@CollectionTable(name = "general_system_settings_supervisor_change_recipient",
joinColumns = @JoinColumn(name = "general_system_settings_id", referencedColumnName = "id"))
@Column(name = "mail")
private List<String> supervisorChangeMails = new ArrayList<>();
@Basic(optional = true)
@Column(name = "project_partner_days_to_live", nullable = true)
private int projectPartnerDaysToLive;
@Basic(optional = false)
@Column(name = "mail_notifications", nullable = false)
private boolean mailNotifications = true;
@Basic(optional = false)
@Column(name = "mail_from_name", nullable = false)
private String mailFromName = "SciPro";
@Basic(optional = false)
@Column(name = "system_from_mail", nullable = false)
private String systemFromMail = "noreply-scipro@dsv.su.se";
@Basic(optional = false)
@Column(name = "smtp_server", nullable = false)
private String smtpServer = "localhost";
@Column(name = "peer_display_latest_reviews")
private boolean peerDisplayLatestReviews = true;
@Basic(optional = false)
@Column(name = "number_of_latest_reviews_displayed", nullable = false)
private int numberOfLatestReviewsDisplayed = DEFAULT_NUMER_OF_LATEST_REVIEWS_DISPLAYED;
@Basic(optional = false)
@Column(name = "public_reviews_activated", nullable = false)
private boolean publicReviewsActivated = true;
@Basic(optional = false)
@Column(name = "peer_download_enabled", nullable = false)
private boolean peerDownloadEnabled = true;
@Basic(optional = false)
@Column(name = "scipro_url", nullable = false)
private String sciproURL = "http://localhost:8080/";
@Basic(optional = false)
@Column(name = "show_single_sign_on", nullable = false)
private boolean showSingleSignOn = true;
@ElementCollection
@Enumerated(EnumType.STRING)
@JoinTable(name = "general_system_settings_system_modules")
@CollectionTable(name = "general_system_settings_system_module",
joinColumns = @JoinColumn(name = "general_system_settings_id", referencedColumnName = "id"))
@Column(name = "system_module")
private Set<SystemModule> systemModules = EnumSet.allOf(SystemModule.class);
@Basic(optional = true)
@Column(name = "match_responsible_mail", nullable = true)
private String matchResponsibleMail = "";
@Basic(optional = true)
@Column(name = "reviewer_support_mail", nullable = true)
private String reviewerSupportMail;
@Basic(optional = true)
@Column(name = "thesis_support_mail", nullable = true)
private String thesisSupportMail;
@Basic(optional = true)
@Column(name = "external_room_booking_url", nullable = true)
private String externalRoomBookingURL;
@Basic(optional = true)
@Column(name = "external_getting_started_with_idea_url", nullable = true)
private String externalGettingStartedWithIdeaURL;
@Basic(optional = true)
@Column(name = "external_grading_url", nullable = true)
private String externalGradingURL;
@Basic(optional = false)
@Column(name = "final_survey_available", nullable = false)
private boolean finalSurveyAvailable = false;
@Basic
@Column(name = "active_project_idea_support_mail")
private String activeProjectIdeaSupportMail;
public GeneralSystemSettings() {

@ -1,6 +1,6 @@
package se.su.dsv.scipro.generalsystemsettings;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject;

@ -16,20 +16,31 @@ import java.time.Instant;
import java.util.Objects;
@Entity
@Table(name = "grading_history_approvals")
@Table(name = "grading_history_approval")
public class ApprovedEvent {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "project_id")
private Project project;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "`when`")
private Instant when;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (grading_history_rejections) referencing
// other tables.
// ----------------------------------------------------------------------------------
@ManyToOne
@JoinColumn(name = "project_id")
private Project project;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
public Long getId() {
return id;
}
@ -38,14 +49,6 @@ public class ApprovedEvent {
this.id = id;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public Instant getWhen() {
return when;
}
@ -54,6 +57,17 @@ public class ApprovedEvent {
this.when = when;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -70,10 +84,7 @@ public class ApprovedEvent {
@Override
public String toString() {
return "ApprovedEvent{" +
"id=" + id +
", project=" + project +
", when=" + when +
'}';
return "ApprovedEvent{" + "id=" + id + ", project=" + project +
", when=" + when + '}';
}
}

@ -1,6 +1,6 @@
package se.su.dsv.scipro.grading;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractRepository;

@ -1,37 +0,0 @@
package se.su.dsv.scipro.grading;
import com.google.inject.Key;
import com.google.inject.PrivateModule;
import com.google.inject.name.Names;
import se.su.dsv.scipro.report.GradingReportServiceImpl;
public class GradingModule extends PrivateModule {
@Override
protected void configure() {
requireBinding(Key.get(String.class, Names.named("service.grading.url")));
bind(GradingService.class).to(GradingServiceImpl.class);
expose(GradingService.class);
bind(PublicationMetadataRepository.class).to(PublicationMetadataRepositoryImpl.class);
bind(PublicationMetadataService.class).to(PublicationMetadataServiceImpl.class);
expose(PublicationMetadataService.class);
bind(ExaminerTimelineService.class).to(GradingHistory.class);
expose(ExaminerTimelineService.class);
bind(GradingHistoryEventRepository.class).to(GradingHistoryEventRepositoryImpl.class);
bind(ThesisRejectionHistoryService.class).to(GradingHistory.class);
expose(ThesisRejectionHistoryService.class);
bind(ThesisApprovedHistoryService.class).to(GradingHistory.class);
expose(ThesisApprovedHistoryService.class);
bind(ThesisSubmissionHistoryService.class).to(GradingHistory.class);
expose(ThesisSubmissionHistoryService.class);
bind(NationalSubjectCategoryRepository.class).to(NationalSubjectCategoryRepositoryImpl.class);
bind(NationalSubjectCategoryService.class).to(NationalSubjectCategoryServiceImpl.class);
expose(NationalSubjectCategoryService.class);
bind(GradingReportTemplateService.class).to(GradingReportServiceImpl.class);
expose(GradingReportTemplateService.class);
}
}

@ -12,21 +12,20 @@ import java.util.Objects;
@Entity
@Table(name = "national_subject_category")
public class NationalSubjectCategory {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = jakarta.persistence.GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Basic
@Column(name = "external_id")
private Integer externalId;
@Basic
@Column(name = "swedish_name")
@Column(name = "name_sv")
private String swedishName;
@Basic
@Column(name = "english_name")
@Column(name = "name_en")
private String englishName;
@Basic
@ -37,9 +36,19 @@ public class NationalSubjectCategory {
@Column(name = "preselected")
private boolean preselected;
@Basic
@Column(name = "external_id")
private Integer externalId;
// ----------------------------------------------------------------------------------
// Constructor
// ----------------------------------------------------------------------------------
public NationalSubjectCategory() {
}
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
public Long getId() {
return id;
}
@ -48,14 +57,6 @@ public class NationalSubjectCategory {
this.id = id;
}
public Integer getExternalId() {
return externalId;
}
public void setExternalId(Integer externalId) {
this.externalId = externalId;
}
public String getSwedishName() {
return swedishName;
}
@ -88,6 +89,17 @@ public class NationalSubjectCategory {
this.preselected = preselected;
}
public Integer getExternalId() {
return externalId;
}
public void setExternalId(Integer externalId) {
this.externalId = externalId;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(Object o) {
if (this == o) {

@ -1,6 +1,6 @@
package se.su.dsv.scipro.grading;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.system.AbstractRepository;

@ -17,34 +17,44 @@ import java.util.Objects;
@Entity
@Table(name = "publication_metadata")
public class PublicationMetadata {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(optional = false)
private Project project;
@Basic
@Column(name = "abstract_swedish")
@Column(name = "abstract_sv")
private String abstractSwedish;
@Basic
@Column(name = "abstract_english")
@Column(name = "abstract_en")
private String abstractEnglish;
@Basic
@Column(name = "keywords_swedish")
@Column(name = "keywords_sv")
private String keywordsSwedish;
@Basic
@Column(name = "keywords_english")
@Column(name = "keywords_en")
private String keywordsEnglish;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (publication_metadata) referencing
// other tables.
// ----------------------------------------------------------------------------------
@ManyToOne
@JoinColumn(name = "national_subject_category_id")
private NationalSubjectCategory nationalSubjectCategory;;
@OneToOne(optional = false)
@JoinColumn(name = "project_id")
private Project project;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
public Long getId() {
return id;
}
@ -53,14 +63,6 @@ public class PublicationMetadata {
this.id = id;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public String getAbstractSwedish() {
return abstractSwedish;
}
@ -101,19 +103,17 @@ public class PublicationMetadata {
this.nationalSubjectCategory = nationalSubjectCategory;
}
@Override
public String toString() {
return "PublicationMetadata{" +
"id=" + id +
", project=" + project +
", abstractSwedish='" + abstractSwedish + '\'' +
", abstractEnglish='" + abstractEnglish + '\'' +
", keywordsSwedish='" + keywordsSwedish + '\'' +
", keywordsEnglish='" + keywordsEnglish + '\'' +
", nationalSubjectCategory=" + nationalSubjectCategory + '\'' +
'}';
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(Object o) {
return o instanceof PublicationMetadata that &&
@ -124,4 +124,15 @@ public class PublicationMetadata {
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "PublicationMetadata{" + "id=" + id + ", project=" + project +
", abstractSwedish='" + abstractSwedish + '\'' +
", abstractEnglish='" + abstractEnglish + '\'' +
", keywordsSwedish='" + keywordsSwedish + '\'' +
", keywordsEnglish='" + keywordsEnglish + '\'' +
", nationalSubjectCategory=" + nationalSubjectCategory + '\'' +
'}';
}
}

@ -2,7 +2,7 @@ package se.su.dsv.scipro.grading;
import se.su.dsv.scipro.project.Project;
interface PublicationMetadataRepository {
public interface PublicationMetadataRepository {
void save(PublicationMetadata publicationMetadata);
PublicationMetadata findByProject(Project project);

@ -1,6 +1,6 @@
package se.su.dsv.scipro.grading;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractRepository;
@ -8,9 +8,9 @@ import se.su.dsv.scipro.system.AbstractRepository;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
class PublicationMetadataRepositoryImpl extends AbstractRepository implements PublicationMetadataRepository {
public class PublicationMetadataRepositoryImpl extends AbstractRepository implements PublicationMetadataRepository {
@Inject
PublicationMetadataRepositoryImpl(Provider<EntityManager> em) {
public PublicationMetadataRepositoryImpl(Provider<EntityManager> em) {
super(em);
}

@ -6,11 +6,11 @@ import se.su.dsv.scipro.system.Language;
import jakarta.inject.Inject;
import java.util.Objects;
class PublicationMetadataServiceImpl implements PublicationMetadataService {
public class PublicationMetadataServiceImpl implements PublicationMetadataService {
private final PublicationMetadataRepository publicationMetadataRepository;
@Inject
PublicationMetadataServiceImpl(PublicationMetadataRepository publicationMetadataRepository) {
public PublicationMetadataServiceImpl(PublicationMetadataRepository publicationMetadataRepository) {
this.publicationMetadataRepository = publicationMetadataRepository;
}

@ -17,23 +17,35 @@ import java.time.Instant;
import java.util.Objects;
@Entity
@Table(name = "grading_history_rejections")
@Table(name = "grading_history_rejection")
public class RejectionEvent {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "project_id")
private Project project;
@Basic
@Column(name = "reason")
private String reason;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "`when`")
private Instant when;
@Basic
private String reason;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (grading_history_rejections) referencing
// other tables.
// ----------------------------------------------------------------------------------
@ManyToOne
@JoinColumn(name = "project_id")
private Project project;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
public Long getId() {
return id;
}
@ -42,22 +54,6 @@ public class RejectionEvent {
this.id = id;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public Instant getWhen() {
return when;
}
public void setWhen(Instant when) {
this.when = when;
}
public String getReason() {
return reason;
}
@ -66,6 +62,25 @@ public class RejectionEvent {
this.reason = reason;
}
public Instant getWhen() {
return when;
}
public void setWhen(Instant when) {
this.when = when;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(Object o) {
if (this == o) return true;

@ -18,27 +18,38 @@ import java.time.Instant;
import java.util.Objects;
@Entity
@Table(name = "grading_history_submissions")
@Table(name = "grading_history_submission")
public class SubmissionEvent {
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "project_id")
private Project project;
@ManyToOne
@JoinColumn(name = "author_id")
private User author;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "`when`")
private Instant when;
@Basic
@Column(name = "corrections")
private String corrections;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (grading_history_submission) referencing
// other tables.
// ----------------------------------------------------------------------------------
@ManyToOne
@JoinColumn(name = "project_id", referencedColumnName = "id")
private Project project;
@ManyToOne
@JoinColumn(name = "author_user_id", referencedColumnName = "id")
private User author;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
public Long getId() {
return id;
}
@ -47,22 +58,6 @@ public class SubmissionEvent {
this.id = id;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public User getAuthor() {
return author;
}
public void setAuthor(User user) {
this.author = user;
}
public Instant getWhen() {
return when;
}
@ -79,6 +74,25 @@ public class SubmissionEvent {
this.corrections = corrections;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public User getAuthor() {
return author;
}
public void setAuthor(User user) {
this.author = user;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -97,11 +111,8 @@ public class SubmissionEvent {
@Override
public String toString() {
return "RejectionEvent{" +
"id=" + id +
", project=" + project +
", author=" + author +
", when=" + when +
return "RejectionEvent{" + "id=" + id + ", project=" + project +
", author=" + author + ", when=" + when +
", corrections='" + corrections + '\'' +
'}';
}

@ -18,30 +18,124 @@ public class Group extends DomainObject {
public static final int STRING_MAX_LENGTH = 255;
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = STRING_MAX_LENGTH)
@Basic(optional = false)
@Column(name = "title", length = STRING_MAX_LENGTH)
private String title;
@Basic(optional = true)
@Column(name = "description")
private String description;
@Basic
@Column(name = "active")
private boolean active = true;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (project_group) referencing other tables.
// ----------------------------------------------------------------------------------
//Creator, should be a supervisor
@ManyToOne(optional = false)
@JoinColumn(name = "user_id")
@JoinColumn(name = "user_id", referencedColumnName = "id")
private User user;
// ----------------------------------------------------------------------------------
// @ManyToMany JPA-mappings
// ----------------------------------------------------------------------------------
@ManyToMany
@JoinTable(
name = "project_group_project",
joinColumns = @JoinColumn(name = "project_group_id"),
inverseJoinColumns = @JoinColumn(name = "project_id"))
@JoinTable(name = "project_group_project",
joinColumns = @JoinColumn(name = "project_group_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "project_id", referencedColumnName = "id"))
private Set<Project> projects = new HashSet<>();
private boolean active = true;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
@Override
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isActive() {
return this.active;
}
public void setActive(boolean active) {
this.active = active;
}
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
public Set<Project> getProjects() {
return projects;
}
public void setProjects(Set<Project> projects) {
this.projects = projects;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof Group)) return false;
final Group other = (Group) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
}
@Override
public String toString() {
return "Group(id=" + this.getId() + ", title=" + this.getTitle() + ", description=" +
this.getDescription() + ", user=" + this.getUser() + ", projects=" +
this.getProjects() + ", active=" + this.isActive() + ")";
}
// ----------------------------------------------------------------------------------
// Other methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof Group;
}
public boolean isAuthor(final User user) {
for (Project project : projects) {
@ -58,76 +152,4 @@ public class Group extends DomainObject {
.filter(member -> member.getType() != Member.Type.REVIEWER)
.toList();
}
public Set<Project> getProjects() {
return projects;
}
public String getTitle() {
return title;
}
@Override
public Long getId() {
return this.id;
}
public String getDescription() {
return this.description;
}
public User getUser() {
return this.user;
}
public boolean isActive() {
return this.active;
}
public void setId(Long id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setDescription(String description) {
this.description = description;
}
public void setUser(User user) {
this.user = user;
}
public void setProjects(Set<Project> projects) {
this.projects = projects;
}
public void setActive(boolean active) {
this.active = active;
}
@Override
public String toString() {
return "Group(id=" + this.getId() + ", title=" + this.getTitle() + ", description=" + this.getDescription() + ", user=" + this.getUser() + ", projects=" + this.getProjects() + ", active=" + this.isActive() + ")";
}
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof Group)) return false;
final Group other = (Group) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
}
protected boolean canEqual(final Object other) {
return other instanceof Group;
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
}
}
}

@ -1,30 +1,49 @@
package se.su.dsv.scipro.integration.activityfinalseminar;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapsId;
import jakarta.persistence.Table;
import se.su.dsv.scipro.activityplan.Activity;
import se.su.dsv.scipro.finalseminar.FinalSeminar;
import jakarta.persistence.*;
import java.io.Serializable;
import java.util.Objects;
@Entity
@Table(name = "activity_final_seminar")
class ActivityFinalSeminar {
// ----------------------------------------------------------------------------------
// embedded JPA-mappings
// ----------------------------------------------------------------------------------
@EmbeddedId
@AttributeOverride(name = "activityId", column = @Column(name = "activity_id"))
@AttributeOverride(name = "finalSeminarId", column = @Column(name = "final_seminar_id"))
private Id id = new Id();
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (activity_final_seminiar) referencing
// other tables.
// ----------------------------------------------------------------------------------
@ManyToOne
@MapsId("activityId")
@JoinColumn(name = "activity_id")
@JoinColumn(name = "activity_id", referencedColumnName = "id")
private Activity activity;
@ManyToOne
@MapsId("finalSeminarId")
@JoinColumn(name = "final_seminar_id")
@JoinColumn(name = "final_seminar_id", referencedColumnName = "id")
private FinalSeminar finalSeminar;
// ----------------------------------------------------------------------------------
// constructor
// ----------------------------------------------------------------------------------
protected ActivityFinalSeminar() {
// JPA
}
@ -34,6 +53,9 @@ class ActivityFinalSeminar {
this.finalSeminar = finalSeminar;
}
// ----------------------------------------------------------------------------------
// getters
// ----------------------------------------------------------------------------------
public Id getId() {
return this.id;
}
@ -46,6 +68,9 @@ class ActivityFinalSeminar {
return this.finalSeminar;
}
// ----------------------------------------------------------------------------------
// other methods
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -57,10 +82,6 @@ class ActivityFinalSeminar {
&& Objects.equals(this.getFinalSeminar(), other.getFinalSeminar());
}
protected boolean canEqual(final Object other) {
return other instanceof ActivityFinalSeminar;
}
@Override
public int hashCode() {
return Objects.hash(this.getId(), this.getActivity(), this.getFinalSeminar());
@ -71,6 +92,13 @@ class ActivityFinalSeminar {
return "ActivityFinalSeminar(id=" + this.getId() + ", activity=" + this.getActivity() + ", finalSeminar=" + this.getFinalSeminar() + ")";
}
protected boolean canEqual(final Object other) {
return other instanceof ActivityFinalSeminar;
}
// ----------------------------------------------------------------------------------
// nested class
// ----------------------------------------------------------------------------------
@Embeddable
static class Id implements Serializable {
private Long activityId;

@ -1,11 +0,0 @@
package se.su.dsv.scipro.integration.activityfinalseminar;
import com.google.inject.AbstractModule;
public class ActivityFinalSeminarModule extends AbstractModule {
@Override
protected void configure() {
bind(FinalSeminarActivityHandler.class).asEagerSingleton();
bind(ActivityFinalSeminarRepository.class).to(ActivityFinalSeminarRepositoryImpl.class);
}
}

@ -1,6 +1,6 @@
package se.su.dsv.scipro.integration.activityfinalseminar;
import com.google.inject.persist.Transactional;
import jakarta.transaction.Transactional;
import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.finalseminar.FinalSeminar;

@ -1,11 +0,0 @@
package se.su.dsv.scipro.integration.activityforum;
import com.google.inject.AbstractModule;
public class ActivityForumModule extends AbstractModule {
@Override
protected void configure() {
bind(PostActivityUploadToForum.class).asEagerSingleton();
bind(ActivityThreadRepository.class).to(ActivityThreadRepositoryImpl.class);
}
}

@ -1,27 +1,44 @@
package se.su.dsv.scipro.integration.activityforum;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapsId;
import jakarta.persistence.Table;
import se.su.dsv.scipro.activityplan.Activity;
import se.su.dsv.scipro.forum.dataobjects.ProjectThread;
import jakarta.persistence.*;
import java.io.Serializable;
import java.util.Objects;
@Entity
@Table(name = "activity_thread")
class ActivityThread {
// ----------------------------------------------------------------------------------
// basic and embedded JPA-mappings
// ----------------------------------------------------------------------------------
@EmbeddedId
private Id id = new Id();
@ManyToOne
@MapsId("threadId")
@JoinColumn(name = "project_thread_id")
private ProjectThread thread;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (activity_thread) referencing other tables.
// ----------------------------------------------------------------------------------
@ManyToOne
@MapsId("activityId")
@JoinColumn(name = "activity_id", referencedColumnName = "id")
private Activity activity;
@ManyToOne
@MapsId("threadId")
@JoinColumn(name = "project_thread_id", referencedColumnName = "id")
private ProjectThread thread;
// ----------------------------------------------------------------------------------
// constructor
// ----------------------------------------------------------------------------------
protected ActivityThread() {
// JPA
}
@ -31,6 +48,9 @@ class ActivityThread {
this.activity = activity;
}
// ----------------------------------------------------------------------------------
// getters and setters
// ----------------------------------------------------------------------------------
public Id getId() {
return this.id;
}
@ -43,6 +63,9 @@ class ActivityThread {
return this.activity;
}
// ----------------------------------------------------------------------------------
// other methods
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
@ -54,10 +77,6 @@ class ActivityThread {
&& Objects.equals(this.getActivity(), other.getActivity());
}
protected boolean canEqual(final Object other) {
return other instanceof ActivityThread;
}
@Override
public int hashCode() {
return Objects.hash(this.getId(), this.getThread(), this.getActivity());
@ -68,6 +87,13 @@ class ActivityThread {
return "ActivityThread(id=" + this.getId() + ", thread=" + this.getThread() + ", activity=" + this.getActivity() + ")";
}
protected boolean canEqual(final Object other) {
return other instanceof ActivityThread;
}
// ----------------------------------------------------------------------------------
// nested class
// ----------------------------------------------------------------------------------
@Embeddable
static class Id implements Serializable {
private Long threadId;

@ -1,5 +1,6 @@
package se.su.dsv.scipro.mail;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.GenerationType;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.system.DomainObject;
@ -19,61 +20,80 @@ import jakarta.persistence.Lob;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.util.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "mail_event")
@Cacheable(false)
public class MailEvent extends DomainObject {
public static final int STRING_MAX_LENGTH = 255;
// ----------------------------------------------------------------------------------
// Basic JPA-mappings
// ----------------------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JoinTable(
name = "mail_event_recipients",
joinColumns = @JoinColumn(name = "mail_event_id"),
inverseJoinColumns = @JoinColumn(name = "recipients_id"))
@ManyToMany(fetch = FetchType.EAGER)
private Set<User> recipients = new HashSet<>();
@ElementCollection
private Set<String> nonUserRecipients = new HashSet<>();
@Column(length = STRING_MAX_LENGTH)
@Basic(optional = false)
@Column(name = "subject", length = STRING_MAX_LENGTH)
private String subject;
@Column(length = STRING_MAX_LENGTH)
@Basic(optional = true)
@Column(name = "from_name", length = STRING_MAX_LENGTH)
private String fromName;
@Column(length = STRING_MAX_LENGTH)
@Basic(optional = true)
@Column(name = "from_email", length = STRING_MAX_LENGTH)
private String fromEmail;
@Lob
@Basic(optional = false)
@Column(name = "message_body")
@Lob
private String messageBody;
@Basic(optional = false)
@Column(name = "sent")
private boolean sent = false;
@Basic(optional = true)
@Column(name = "message_id")
private String messageID;
// ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (mail_event) referencing other
// tables.
// ----------------------------------------------------------------------------------
@ManyToOne(optional = true)
@JoinColumn(name = "attachment_reference_id")
@JoinColumn(name = "attachment_file_reference_id", referencedColumnName = "id")
private FileReference attachment;
// ----------------------------------------------------------------------------------
// @ManyToMany JPA-mappings
// ----------------------------------------------------------------------------------
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "mail_event_recipient",
joinColumns = @JoinColumn(name = "mail_event_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "recipient_id", referencedColumnName = "id"))
private Set<User> recipients = new HashSet<>();
@ElementCollection
@CollectionTable(name = "mail_event_non_user_recipient",
joinColumns = @JoinColumn(name = "mail_event_id", referencedColumnName = "id"))
@Column(name = "non_user_recipient")
private Set<String> nonUserRecipients = new HashSet<>();
// ----------------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------------
public MailEvent() {
}
public MailEvent(
final String subject,
final String messageBody,
final User recipient,
final String fromName,
public MailEvent(final String subject, final String messageBody, final User recipient, final String fromName,
final String fromEmail) {
this.subject = subject;
this.messageBody = messageBody;
@ -82,13 +102,8 @@ public class MailEvent extends DomainObject {
this.fromEmail = fromEmail;
}
public MailEvent(
final String subject,
final String messageBody,
final Collection<User> recipients,
final String fromName,
final String fromEmail
) {
public MailEvent(final String subject, final String messageBody, final Collection<User> recipients,
final String fromName, final String fromEmail) {
this.subject = subject;
this.messageBody = messageBody;
this.recipients.addAll(recipients);
@ -96,35 +111,124 @@ public class MailEvent extends DomainObject {
this.fromEmail = fromEmail;
}
public boolean isSent() {
return sent;
// ----------------------------------------------------------------------------------
// Properties (Getters and Setters)
// ----------------------------------------------------------------------------------
@Override
public Long getId() {
return this.id;
}
public void markSent(final String messageID) {
this.messageID = messageID;
this.sent = true;
public void setId(Long id) {
this.id = id;
}
public Set<User> getRecipients() {
return recipients;
}
public void setMessageBody(String messageBody) {
this.messageBody = messageBody;
public String getSubject() {
return this.subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getFromName() {
return this.fromName;
}
public void setFromName(String fromName) {
this.fromName = fromName;
}
public String getFromEmail() {
return this.fromEmail;
}
public void setFromEmail(String fromEmail) {
this.fromEmail = fromEmail;
}
public String getMessageBody() {
return this.messageBody;
}
public void setMessageBody(String messageBody) {
this.messageBody = messageBody;
}
public boolean isSent() {
return sent;
}
public void setSent(boolean sent) {
this.sent = sent;
}
public String getMessageID() {
return this.messageID;
}
public void setMessageID(String messageID) {
this.messageID = messageID;
}
public FileReference getAttachment() {
return this.attachment;
}
public void setAttachment(FileReference attachment) {
this.attachment = attachment;
}
public Set<User> getRecipients() {
return recipients;
}
public void setRecipients(Set<User> recipients) {
this.recipients = recipients;
}
public Set<String> getNonUserRecipients() {
return this.nonUserRecipients;
}
public void setNonUserRecipients(Set<String> nonUserRecipients) {
this.nonUserRecipients = nonUserRecipients;
}
// ----------------------------------------------------------------------------------
// Methods Common To All Objects
// ----------------------------------------------------------------------------------
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof MailEvent)) return false;
final MailEvent other = (MailEvent) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
}
@Override
public String toString() {
return "MailEvent(id=" + this.getId() + ", recipients=" + this.getRecipients() +
", nonUserRecipients=" + this.getNonUserRecipients() + ", subject=" +
this.getSubject() + ", fromName=" + this.getFromName() +
", fromEmail=" + this.getFromEmail() + ", messageBody=" + this.getMessageBody() +
", sent=" + this.isSent() + ", messageID=" + this.getMessageID() +
", attachment=" + this.getAttachment() + ")";
}
// ----------------------------------------------------------------------------------
// Other Methods
// ----------------------------------------------------------------------------------
protected boolean canEqual(final Object other) {
return other instanceof MailEvent;
}
public void addRecipients(final Iterable<Recipient> recipients) {
for (Recipient recipient : recipients) {
recipient.accept(new RecipientVisitor<Boolean>() {
@ -141,83 +245,8 @@ public class MailEvent extends DomainObject {
}
}
@Override
public Long getId() {
return this.id;
}
public Set<String> getNonUserRecipients() {
return this.nonUserRecipients;
}
public String getSubject() {
return this.subject;
}
public String getFromName() {
return this.fromName;
}
public String getFromEmail() {
return this.fromEmail;
}
public String getMessageBody() {
return this.messageBody;
}
public String getMessageID() {
return this.messageID;
}
public FileReference getAttachment() {
return this.attachment;
}
public void setId(Long id) {
this.id = id;
}
public void setRecipients(Set<User> recipients) {
this.recipients = recipients;
}
public void setNonUserRecipients(Set<String> nonUserRecipients) {
this.nonUserRecipients = nonUserRecipients;
}
public void setSent(boolean sent) {
this.sent = sent;
}
public void setMessageID(String messageID) {
public void markSent(final String messageID) {
this.messageID = messageID;
}
public void setAttachment(FileReference attachment) {
this.attachment = attachment;
}
@Override
public String toString() {
return "MailEvent(id=" + this.getId() + ", recipients=" + this.getRecipients() + ", nonUserRecipients=" + this.getNonUserRecipients() + ", subject=" + this.getSubject() + ", fromName=" + this.getFromName() + ", fromEmail=" + this.getFromEmail() + ", messageBody=" + this.getMessageBody() + ", sent=" + this.isSent() + ", messageID=" + this.getMessageID() + ", attachment=" + this.getAttachment() + ")";
}
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof MailEvent)) return false;
final MailEvent other = (MailEvent) o;
return other.canEqual(this)
&& Objects.equals(this.getId(), other.getId());
}
protected boolean canEqual(final Object other) {
return other instanceof MailEvent;
}
@Override
public int hashCode() {
return Objects.hashCode(this.getId());
this.sent = true;
}
}

@ -6,7 +6,7 @@ import se.su.dsv.scipro.file.FileDescription;
import java.util.Arrays;
import java.util.UUID;
class PrintingMailer implements Mailer {
public class PrintingMailer implements Mailer {
@Override
public MailResult mail(final String fromName, final String fromEmail, final String[] recipients, final String subject, final String message, final FileDescription attachment) {
return new MailResult() {

@ -1,6 +1,6 @@
package se.su.dsv.scipro.match;
class AllowAllIdeaCreationJudge implements IdeaCreationJudge {
public class AllowAllIdeaCreationJudge implements IdeaCreationJudge {
@Override
public Decision ruling(Idea idea) {
return Decision.allowed();

@ -1,17 +1,30 @@
package se.su.dsv.scipro.match;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import jakarta.persistence.Basic;
import jakarta.persistence.Cacheable;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import se.su.dsv.scipro.system.DomainObject;
import se.su.dsv.scipro.system.ProjectType;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
@Entity
@Cacheable(true)
@Table(name="ApplicationPeriod")
@Table(name="application_period")
public class ApplicationPeriod extends DomainObject {
@Id
@ -23,17 +36,16 @@ public class ApplicationPeriod extends DomainObject {
private String name;
@Basic
@Column(name = "start_date")
private LocalDate startDate = LocalDate.now();
@Basic
@Column(name = "end_date")
private LocalDate endDate = LocalDate.now();
@Basic
@Column(name = "courseStartDate")
@Column(name = "course_start_date")
private LocalDateTime courseStartDateTime = LocalDate.now().atTime(8, 0);
@Basic
@Column(name = "course_end_date")
private LocalDate courseEndDate;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "applicationPeriod", cascade=CascadeType.ALL, orphanRemoval=true)

@ -1,15 +1,23 @@
package se.su.dsv.scipro.match;
import se.su.dsv.scipro.system.User;
import jakarta.persistence.*;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Objects;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.Column;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapsId;
import jakarta.persistence.Table;
import se.su.dsv.scipro.system.User;
@Entity
@Table(name = "applicationperiodexemption")
@Table(name = "application_period_exemption")
public class ApplicationPeriodExemption implements Serializable {
public enum Type {
SUBMIT_STUDENT_IDEA(true),
@ -39,16 +47,19 @@ public class ApplicationPeriodExemption implements Serializable {
@MapsId("applicationPeriodId")
@ManyToOne(optional = false)
@JoinColumn(name = "applicationPeriodId")
@JoinColumn(name = "application_period_id")
private ApplicationPeriod applicationPeriod;
@Column(name = "end_date")
private LocalDate endDate;
private String comment;
@ManyToOne(optional = false)
@JoinColumn(name = "granted_by_id")
private User grantedBy;
@Column(name = "granted_on")
private LocalDateTime grantedOn;
public ApplicationPeriodExemptionId getApplicationperiodexemptionId() {

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