From 55ee3581f19def40ca5258a8a2587b050f18f13c Mon Sep 17 00:00:00 2001
From: Andreas Svanberg <andreass@dsv.su.se>
Date: Tue, 14 May 2024 14:07:20 +0200
Subject: [PATCH] Sort of working

---
 core/pom.xml                                  |   4 +
 .../serviceimpls/UserProfileServiceImpl.java  |   1 +
 pom.xml                                       |  13 +-
 view/pom.xml                                  |   8 +
 view/src/main/java/ApplicationBootstrap.java  | 152 +++++++++++++++++-
 .../se/su/dsv/scipro/api/ApiController.java   |  29 ++++
 6 files changed, 192 insertions(+), 15 deletions(-)
 create mode 100644 view/src/main/java/se/su/dsv/scipro/api/ApiController.java

diff --git a/core/pom.xml b/core/pom.xml
index df548c1fad..240d9afd5a 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -87,6 +87,10 @@
             <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>
diff --git a/core/src/main/java/se/su/dsv/scipro/springdata/serviceimpls/UserProfileServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/springdata/serviceimpls/UserProfileServiceImpl.java
index a89512dab1..dcb7c76e2b 100644
--- a/core/src/main/java/se/su/dsv/scipro/springdata/serviceimpls/UserProfileServiceImpl.java
+++ b/core/src/main/java/se/su/dsv/scipro/springdata/serviceimpls/UserProfileServiceImpl.java
@@ -43,6 +43,7 @@ public class UserProfileServiceImpl extends AbstractServiceImpl<UserProfile, Lon
     }
 
     @Override
+    @jakarta.transaction.Transactional
     public void setSelectedRole(User user, Roles role) {
         UserProfile profile = findByUser(user);
         profile.setSelectedRole(role);
diff --git a/pom.xml b/pom.xml
index ecec44db58..4e6554cb35 100755
--- a/pom.xml
+++ b/pom.xml
@@ -98,14 +98,11 @@
             </dependency>
 
             <dependency>
-                <groupId>org.springframework</groupId>
-                <artifactId>spring-web</artifactId>
-                <version>6.1.4</version>
-            </dependency>
-            <dependency>
-                <groupId>org.springframework</groupId>
-                <artifactId>spring-orm</artifactId>
-                <version>6.1.4</version>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>3.2.5</version>
+                <scope>import</scope>
+                <type>pom</type>
             </dependency>
 
             <!--  Servlet API, needed for compilation. -->
diff --git a/view/pom.xml b/view/pom.xml
index c3d712fecd..9aa1558309 100644
--- a/view/pom.xml
+++ b/view/pom.xml
@@ -99,6 +99,14 @@
             <groupId>org.springframework</groupId>
             <artifactId>spring-orm</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-tx</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+        </dependency>
 
         <!--  Servlet API, needed for compilation. -->
         <dependency>
diff --git a/view/src/main/java/ApplicationBootstrap.java b/view/src/main/java/ApplicationBootstrap.java
index b30d3094af..3bab9cef41 100644
--- a/view/src/main/java/ApplicationBootstrap.java
+++ b/view/src/main/java/ApplicationBootstrap.java
@@ -1,22 +1,61 @@
+import com.google.common.eventbus.EventBus;
 import jakarta.inject.Named;
 import jakarta.inject.Provider;
 import jakarta.inject.Singleton;
 import jakarta.persistence.EntityManager;
 import jakarta.persistence.EntityManagerFactory;
-import jakarta.persistence.Persistence;
 import jakarta.servlet.ServletContext;
 import jakarta.servlet.ServletException;
 import org.apache.wicket.protocol.http.WicketFilter;
 import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.task.SimpleAsyncTaskExecutor;
+import org.springframework.orm.jpa.LocalEntityManagerFactoryBean;
+import org.springframework.orm.jpa.SharedEntityManagerCreator;
 import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
 import org.springframework.web.WebApplicationInitializer;
 import org.springframework.web.context.ContextLoaderListener;
 import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
+import org.springframework.web.servlet.DispatcherServlet;
 import se.su.dsv.scipro.SciProApplication;
+import se.su.dsv.scipro.daisyExternal.http.DaisyAPI;
+import se.su.dsv.scipro.daisyExternal.http.DaisyAPIImpl;
+import se.su.dsv.scipro.file.FileService;
+import se.su.dsv.scipro.finalseminar.AuthorRepository;
+import se.su.dsv.scipro.finalseminar.FinalSeminarActiveParticipationRepository;
+import se.su.dsv.scipro.finalseminar.FinalSeminarOppositionRepo;
+import se.su.dsv.scipro.finalseminar.FinalSeminarRepository;
+import se.su.dsv.scipro.finalseminar.FinalSeminarService;
+import se.su.dsv.scipro.finalseminar.FinalSeminarServiceImpl;
+import se.su.dsv.scipro.finalseminar.FinalSeminarSettingsService;
+import se.su.dsv.scipro.finalseminar.FinalSeminarSettingsServiceImpl;
 import se.su.dsv.scipro.gdpr.Reporter;
+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.notifications.NotificationService;
+import se.su.dsv.scipro.notifications.NotificationServiceImpl;
 import se.su.dsv.scipro.profiles.CurrentProfile;
+import se.su.dsv.scipro.project.ProjectRepo;
+import se.su.dsv.scipro.project.ProjectRepoImpl;
+import se.su.dsv.scipro.project.ProjectService;
+import se.su.dsv.scipro.project.ProjectServiceImpl;
+import se.su.dsv.scipro.report.OppositionReportService;
+import se.su.dsv.scipro.report.OppositionReportServiceImpl;
+import se.su.dsv.scipro.reviewing.RoughDraftApprovalService;
+import se.su.dsv.scipro.springdata.serviceimpls.UserProfileServiceImpl;
+import se.su.dsv.scipro.springdata.services.UserProfileService;
+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.FooterLinkService;
+import se.su.dsv.scipro.system.FooterLinkServiceImpl;
 import se.su.dsv.scipro.system.Lifecycle;
 import se.su.dsv.scipro.system.ResearchArea;
 import se.su.dsv.scipro.system.User;
@@ -24,10 +63,9 @@ import se.su.dsv.scipro.system.UserImportService;
 import se.su.dsv.scipro.system.UserService;
 import se.su.dsv.scipro.system.UserServiceImpl;
 
-import java.io.IOException;
 import java.net.CookieHandler;
 import java.net.CookieManager;
-import java.nio.file.Path;
+import java.time.Clock;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
@@ -40,10 +78,13 @@ public class ApplicationBootstrap implements WebApplicationInitializer {
         // preserve cookies when using Jersey which will use the logged in session cookie from
         // Daisy API thus drastically speeding up the batch jobs
         CookieHandler.setDefault(new CookieManager());
+
         AnnotationConfigWebApplicationContext webApplicationContext = new AnnotationConfigWebApplicationContext();
+        webApplicationContext.setServletContext(servletContext);
         webApplicationContext.register(SciProApplication.class);
         webApplicationContext.register(CurrentProfile.class);
         webApplicationContext.register(Config.class);
+        webApplicationContext.scan("se.su.dsv.scipro.api");
         webApplicationContext.refresh();
 
         servletContext.addListener(new ContextLoaderListener(webApplicationContext));
@@ -60,9 +101,13 @@ public class ApplicationBootstrap implements WebApplicationInitializer {
 
         servletContext.addFilter("wicket-filter", filter)
                 .addMappingForUrlPatterns(null, true, "/*");
+
+        servletContext.addServlet("spring-web", new DispatcherServlet(webApplicationContext))
+                .addMapping("/api/*");
     }
 
     @Configuration
+    @EnableTransactionManagement
     public static class Config {
         @Bean
         @Named("profile")
@@ -92,14 +137,16 @@ public class ApplicationBootstrap implements WebApplicationInitializer {
 
         @Bean
         @Singleton
-        public EntityManagerFactory entityManagerFactory() {
-            System.out.println("Creating EntityManagerFactory");
-            return Persistence.createEntityManagerFactory("defaultPersistenceUnit");
+        public LocalEntityManagerFactoryBean entityManagerFactory() {
+            LocalEntityManagerFactoryBean localEntityManagerFactoryBean = new LocalEntityManagerFactoryBean();
+            localEntityManagerFactoryBean.setPersistenceUnitName("defaultPersistenceUnit");
+            localEntityManagerFactoryBean.setBootstrapExecutor(new SimpleAsyncTaskExecutor());
+            return localEntityManagerFactoryBean;
         }
 
         @Bean
         public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
-            return entityManagerFactory.createEntityManager();
+            return SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory);
         }
 
         @Bean
@@ -107,6 +154,11 @@ public class ApplicationBootstrap implements WebApplicationInitializer {
             return new UserServiceImpl(entityManagerProvider);
         }
 
+        @Bean
+        public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
+            return new org.springframework.orm.jpa.JpaTransactionManager(entityManagerFactory);
+        }
+
         @Bean
         public UserImportService importService() {
             return new UserImportService() {
@@ -130,5 +182,91 @@ public class ApplicationBootstrap implements WebApplicationInitializer {
                 }
             };
         }
+
+        @Bean
+        public UserProfileService userProfileService(Provider<EntityManager> em) {
+            return new UserProfileServiceImpl(em);
+        }
+
+        @Bean
+        public NotificationService notificationService(Provider<EntityManager> em) {
+            return new NotificationServiceImpl(em);
+        }
+
+        @Bean
+        public FooterLinkService footerLinkService(FooterLinkRepo repository) {
+            return new FooterLinkServiceImpl(repository);
+        }
+
+        @Bean
+        public FooterLinkRepo footerLinkRepo(Provider<EntityManager> em) {
+            return new FooterLinkRepoImpl(em);
+        }
+
+        @Bean
+        public FooterAddressRepo footerAddressRepo(Provider<EntityManager> em) {
+            return new FooterAddressRepoImpl(em);
+        }
+
+        @Bean
+        public ProjectService projectService(Provider<EntityManager> em, ProjectRepo projectRepo, Clock clock,
+                EventBus eventBus) {
+            return new ProjectServiceImpl(projectRepo, clock, eventBus, em);
+        }
+
+        @Bean
+        public ProjectRepo projectRepo(Provider<EntityManager> em) {
+            return new ProjectRepoImpl(em);
+        }
+
+        @Bean
+        public Clock clock() {
+            return Clock.systemDefaultZone();
+        }
+
+        @Bean
+        public EventBus eventBus() {
+            return new EventBus();
+        }
+
+        @Bean
+        public FinalSeminarService finalSeminarService(Provider<EntityManager> em, EventBus eventBus, Clock clock) {
+            AuthorRepository authorRepository = null;
+            FileService fileService = null;
+            FinalSeminarOppositionRepo finalSeminarOppositionRepository = null;
+            FinalSeminarActiveParticipationRepository finalSeminarActiveParticipantRepository = null;
+            FinalSeminarRepository finalSeminarRepository = null;
+            RoughDraftApprovalService roughDraftApprovalService = null;
+            return new FinalSeminarServiceImpl(em, eventBus, authorRepository, fileService, finalSeminarOppositionRepository, finalSeminarActiveParticipantRepository, finalSeminarRepository, clock, roughDraftApprovalService);
+        }
+
+        @Bean
+        public FinalSeminarSettingsService finalSeminarSettingsService(Provider<EntityManager> em) {
+            return new FinalSeminarSettingsServiceImpl(em);
+        }
+
+        @Bean
+        public NonWorkDayPeriodService nonWorkDayPeriodService(Provider<EntityManager> em) {
+            return new NonWorkDayPeriodServiceImpl(em);
+        }
+
+        @Bean
+        public DaysService daysService(NonWorkDayPeriodService nonWorkDays) {
+            return new DaysServiceImpl(nonWorkDays);
+        }
+
+        @Bean
+        public OppositionReportService oppositionReportService(Provider<EntityManager> em) {
+            return new OppositionReportServiceImpl(null, null, null, null);
+        }
+
+        @Bean
+        public DaisyAPI daisyAPI(
+                @Value("${daisy.api.url}") String baseUrl,
+                @Value("${daisy.api.username}") String username,
+                @Value("${daisy.api.password}") String password)
+        {
+            return new DaisyAPIImpl(baseUrl, username, password);
+        }
     }
 }
diff --git a/view/src/main/java/se/su/dsv/scipro/api/ApiController.java b/view/src/main/java/se/su/dsv/scipro/api/ApiController.java
new file mode 100644
index 0000000000..8059cdde66
--- /dev/null
+++ b/view/src/main/java/se/su/dsv/scipro/api/ApiController.java
@@ -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 + "!";
+    }
+}