From 08763e5139711d95506335937359d3cb150f818c Mon Sep 17 00:00:00 2001 From: Gaydamakha <mikhail.gaydamakha@etu.unistra.fr> Date: Wed, 20 Oct 2021 12:50:04 +0200 Subject: [PATCH] :recycle: Use dependency injection for categories controller --- build.gradle | 5 ++ .../fr/unistra/sil/erp/back/WebMvcConfig.java | 72 ++++++++++++------- .../api/ApiRetrieveCategoriesController.java | 42 +++++------ .../repository/ICategoriesRepository.java | 15 ++++ .../erp/back/repository/SqliteRepository.java | 44 ++++++++++++ .../category/SqliteCategoryRepository.java | 49 +++++++++++++ .../sil/erp/back/repository/package-info.java | 4 ++ ...itional-spring-configuration-metadata.json | 9 +++ src/main/resources/application.properties | 2 + 9 files changed, 193 insertions(+), 49 deletions(-) create mode 100644 src/main/java/fr/unistra/sil/erp/back/repository/ICategoriesRepository.java create mode 100644 src/main/java/fr/unistra/sil/erp/back/repository/SqliteRepository.java create mode 100644 src/main/java/fr/unistra/sil/erp/back/repository/category/SqliteCategoryRepository.java create mode 100644 src/main/java/fr/unistra/sil/erp/back/repository/package-info.java create mode 100644 src/main/resources/META-INF/additional-spring-configuration-metadata.json diff --git a/build.gradle b/build.gradle index a85e402..89164a4 100644 --- a/build.gradle +++ b/build.gradle @@ -5,6 +5,10 @@ plugins { id 'war' } +tasks { + compileJava.inputs.files(processResources) +} + group = 'fr.unistra.sil' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' @@ -24,6 +28,7 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation 'org.thymeleaf:thymeleaf-spring5' + annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" } javadoc { diff --git a/src/main/java/fr/unistra/sil/erp/back/WebMvcConfig.java b/src/main/java/fr/unistra/sil/erp/back/WebMvcConfig.java index 86f0a21..2842710 100644 --- a/src/main/java/fr/unistra/sil/erp/back/WebMvcConfig.java +++ b/src/main/java/fr/unistra/sil/erp/back/WebMvcConfig.java @@ -5,45 +5,47 @@ package fr.unistra.sil.erp.back; import fr.unistra.sil.erp.back.interceptor.api.ApiAuthenticationInterceptor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.context.annotation.PropertySources; +import org.springframework.context.annotation.*; import org.springframework.core.env.Environment; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.logging.Level; +import java.util.logging.Logger; + /** * Main configuration file for the application. + * * @author BEAUVAIS ANTOINE */ @Configuration -@PropertySources( - @PropertySource("/apikey.properties") -) +@EnableWebMvc public class WebMvcConfig implements WebMvcConfigurer { - + /** * Autowired environment for retrieving properties. */ - @Autowired - private Environment env; - + private final Environment env; + /** * API version. */ public static final String API_VERSION = "v1"; - + /** * API prefix. */ public static final String API_PREFIX = "/api/"; - + /** * Prefix for API calls. */ public static final String API_FULL_PREFIX = API_PREFIX + API_VERSION; - + /** * API Mapping for retrieving all items. */ @@ -72,29 +74,47 @@ public class WebMvcConfig implements WebMvcConfigurer { * Web mapping for the login page. */ public static final String MAPPING_LOGIN = "/login"; - + /** * Web mapping for the items list. */ public static final String WEB_MAPPING_ITEMS = "/products"; - + + public WebMvcConfig(Environment env) { + this.env = env; + } + /** * Adds interceptors to the application. - * - * Interceptors process HTTP requests before they reach their + * <p> + * Interceptors process HTTP requests before they reach their * attributed methods. - * - * Currently, interceptors are only used for authentication in this + * <p> + * Currently, interceptors are only used for authentication in this * application. - * + * * @param registry the Interceptor Registry to use for additions. */ @Override public void addInterceptors(InterceptorRegistry registry) { - - registry.addInterceptor(new ApiAuthenticationInterceptor( - this.env.getProperty("api.key"))) - .addPathPatterns(API_PREFIX + "**"); - + registry.addInterceptor(new ApiAuthenticationInterceptor(this.env.getRequiredProperty("api.key"))).addPathPatterns(API_PREFIX + "**"); + } + + /** + * SQL Connection object. + */ + private Connection conn; + + @Bean + public Connection connection() { + if (this.conn == null) { + try { + conn = DriverManager.getConnection(env.getRequiredProperty("spring.datasource.url")); + } catch (SQLException ex) { + Logger.getLogger(this.getClass().getName()).log( + Level.SEVERE, "Failed to connect to SQLite file.", ex); + } + } + return conn; } } diff --git a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveCategoriesController.java b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveCategoriesController.java index a2c01ba..d7e4d45 100644 --- a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveCategoriesController.java +++ b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveCategoriesController.java @@ -5,50 +5,46 @@ package fr.unistra.sil.erp.back.controller.api; import static fr.unistra.sil.erp.back.WebMvcConfig.MAPPING_GETCATEGORIES; -import fr.unistra.sil.erp.back.DatabaseSystem; + import fr.unistra.sil.erp.back.controller.IRetrieveCategoriesController; import fr.unistra.sil.erp.back.model.Category; -import fr.unistra.sil.erp.back.db.DatabaseConnectionException; + import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; + +import fr.unistra.sil.erp.back.repository.ICategoriesRepository; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import fr.unistra.sil.erp.back.db.IDatabase; /** * REST controller for the category list. + * * @author BEAUVAIS ANTOINE */ @RestController -public class ApiRetrieveCategoriesController - implements IRetrieveCategoriesController { - +public class ApiRetrieveCategoriesController implements IRetrieveCategoriesController { + + private final ICategoriesRepository repository; + + public ApiRetrieveCategoriesController(ICategoriesRepository repository) { + this.repository = repository; + } + /** * Returns the list of categories in JSON format. + * * @return the HTTP response. * @throws ApiServerErrorException Database failure. */ @GetMapping(MAPPING_GETCATEGORIES) @Override - public ResponseEntity<Object> getCategories() throws ApiServerErrorException - { - IDatabase db; - try { - db = DatabaseSystem.getInstance(); - } catch (DatabaseConnectionException ex) { - Logger.getLogger(ApiRetrieveCategoriesController.class.getName()) - .log(Level.SEVERE, "Failed to connect to database.", ex); - throw new ApiServerErrorException("Database failure."); - } - - List<Category> res = db.getCategories(); - if(res == null) + public ResponseEntity<Object> getCategories() throws ApiServerErrorException { + List<Category> res = repository.getCategories(); + if (res == null) throw new ApiServerErrorException("Database failure."); - + return new ResponseEntity<>(res, HttpStatus.OK); } - + } diff --git a/src/main/java/fr/unistra/sil/erp/back/repository/ICategoriesRepository.java b/src/main/java/fr/unistra/sil/erp/back/repository/ICategoriesRepository.java new file mode 100644 index 0000000..f9287e0 --- /dev/null +++ b/src/main/java/fr/unistra/sil/erp/back/repository/ICategoriesRepository.java @@ -0,0 +1,15 @@ +package fr.unistra.sil.erp.back.repository; + +import fr.unistra.sil.erp.back.model.Category; + +import java.util.List; + +public interface ICategoriesRepository { + + /** + * Returns the list of all categories. + * + * @return the list of categories, or null if an error occurred. + */ + List<Category> getCategories(); +} diff --git a/src/main/java/fr/unistra/sil/erp/back/repository/SqliteRepository.java b/src/main/java/fr/unistra/sil/erp/back/repository/SqliteRepository.java new file mode 100644 index 0000000..11e239b --- /dev/null +++ b/src/main/java/fr/unistra/sil/erp/back/repository/SqliteRepository.java @@ -0,0 +1,44 @@ +package fr.unistra.sil.erp.back.repository; + +import org.springframework.stereotype.Repository; + +import java.sql.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +@Repository +public class SqliteRepository { + + /** + * SQL Connection object. + */ + private final Connection conn; + + /** + * Class constructor. + */ + public SqliteRepository(Connection conn) { + this.conn = conn; + } + + /** + * Executes a standard query, without parameters. + * + * @param query the string's query. + * @return the result set for this query. + */ + protected ResultSet query(String query) { + Statement stmt; + ResultSet rs; + try { + stmt = this.conn.createStatement(); + rs = stmt.executeQuery(query); + } catch (SQLException ex) { + Logger.getLogger(this.getClass().getName()).log( + Level.SEVERE, "Failed to run query: " + query, ex); + return null; + } + + return rs; + } +} diff --git a/src/main/java/fr/unistra/sil/erp/back/repository/category/SqliteCategoryRepository.java b/src/main/java/fr/unistra/sil/erp/back/repository/category/SqliteCategoryRepository.java new file mode 100644 index 0000000..aec5070 --- /dev/null +++ b/src/main/java/fr/unistra/sil/erp/back/repository/category/SqliteCategoryRepository.java @@ -0,0 +1,49 @@ +package fr.unistra.sil.erp.back.repository.category; + +import fr.unistra.sil.erp.back.model.Category; +import fr.unistra.sil.erp.back.repository.ICategoriesRepository; +import fr.unistra.sil.erp.back.repository.SqliteRepository; +import org.springframework.stereotype.Repository; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +@Repository +public class SqliteCategoryRepository extends SqliteRepository implements ICategoriesRepository { + + /** + * Query used to retrieve all categories stored in the database. + */ + private static final String SQL_GETCATEGORIES = + "SELECT id, name FROM categories"; + + public SqliteCategoryRepository(Connection conn) { + super(conn); + } + + @Override + public List<Category> getCategories() { + ResultSet rs = this.query(SQL_GETCATEGORIES); + if (rs == null) + return null; + + List<Category> res = new ArrayList<>(); + try { + while (rs.next()) { + Category c = new Category(rs.getInt("id"), rs.getString("name")); + res.add(c); + } + } catch (SQLException ex) { + Logger.getLogger(this.getClass().getName()).log( + Level.SEVERE, "Failed to fetch results.", ex); + return null; + } + + return res; + } +} diff --git a/src/main/java/fr/unistra/sil/erp/back/repository/package-info.java b/src/main/java/fr/unistra/sil/erp/back/repository/package-info.java new file mode 100644 index 0000000..a73a187 --- /dev/null +++ b/src/main/java/fr/unistra/sil/erp/back/repository/package-info.java @@ -0,0 +1,4 @@ +/** + * Database interfaces and implementations. + */ +package fr.unistra.sil.erp.back.repository; \ No newline at end of file diff --git a/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 0000000..aa23278 --- /dev/null +++ b/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,9 @@ +{ + "properties": [ + { + "name": "api.key", + "type": "java.lang.String", + "description": "Api key to access the server. Should be added to the HTTP-header ''." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6e04b84..9131178 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,3 @@ spring.mvc.static-path-pattern=/static/** +api.key=someKey +spring.datasource.url=jdbc:sqlite:dev.db -- GitLab