diff --git a/pom.xml b/pom.xml index 290fa836..86487ac8 100644 --- a/pom.xml +++ b/pom.xml @@ -46,9 +46,9 @@ runtime - org.wikidata.wdtk - wdtk-dumpfiles - 0.14.4 + com.fasterxml.jackson.core + jackson-databind + 2.16.1 org.springframework.boot diff --git a/src/main/java/com/uniovi/components/QuestionGeneratorTestController.java b/src/main/java/com/uniovi/components/QuestionGeneratorTestController.java new file mode 100644 index 00000000..82ba147e --- /dev/null +++ b/src/main/java/com/uniovi/components/QuestionGeneratorTestController.java @@ -0,0 +1,24 @@ +package com.uniovi.components; + +import com.uniovi.components.generators.geography.CapitalQuestionGenerator; +import com.uniovi.entities.Question; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +public class QuestionGeneratorTestController { + + @Autowired + CapitalQuestionGenerator qgen; + + @RequestMapping("/test") + public void test() { + List q = qgen.getQuestions(); + for(Question question : q){ + System.out.println(question); + } + } +} diff --git a/src/main/java/com/uniovi/components/generators/AbstractQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/AbstractQuestionGenerator.java new file mode 100644 index 00000000..cb4d46ab --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/AbstractQuestionGenerator.java @@ -0,0 +1,88 @@ +package com.uniovi.components.generators; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.uniovi.entities.Answer; +import com.uniovi.entities.Category; +import com.uniovi.entities.Question; +import com.uniovi.services.CategoryService; + +import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +public abstract class AbstractQuestionGenerator implements QuestionGenerator{ + + private List questions = new ArrayList<>(); + protected final CategoryService categoryService; + private String query; + protected String statement; + + protected AbstractQuestionGenerator(CategoryService categoryService) { + this.categoryService = categoryService; + } + + public void questionGenerator(String statement, List options, String correctAnswer, Category category){ + List answers = new ArrayList<>(); + //Generamos las respuestas y las aƱadimos a la lista + for(String s: options){ + Answer answer = new Answer(s, false); + answers.add(answer); + } + //Generamos la respuesta correcta y la aƱadimos a la lista + Answer correct = new Answer(correctAnswer, true); + answers.add(correct); + + Question question = new Question(statement, answers, correct, category); + question.scrambleOptions(); + questions.add(question); + } + + public List getQuestions() { + HttpClient client = HttpClient.newHttpClient(); + try { + + String endpointUrl = "https://query.wikidata.org/sparql?query=" + + URLEncoder.encode(this.getQuery(), StandardCharsets.UTF_8.toString()) + + "&format=json"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(endpointUrl)) + .header("Accept", "application/json") + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Process the JSON response using Jackson ObjectMapper + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonResponse = objectMapper.readTree(response.body()); + + // Access the data from the JSON response + JsonNode resultsNode = jsonResponse.path("results").path("bindings"); + + for (JsonNode result : resultsNode) { + + List options = this.generateOptions(resultsNode, result); + String correctAnswer = this.generateCorrectAnswer(result); + String statement = this.getQuestionSubject(result); + questionGenerator(statement, options, correctAnswer, this.getCategory()); + + } + } catch (Exception e) { + throw new RuntimeException(e); + } + + return questions; + } + + protected abstract List generateOptions(JsonNode results, JsonNode result); + protected abstract String generateCorrectAnswer(JsonNode result); + + protected abstract String getQuestionSubject(JsonNode result); + +} diff --git a/src/main/java/com/uniovi/components/generators/QuestionGenerator.java b/src/main/java/com/uniovi/components/generators/QuestionGenerator.java new file mode 100644 index 00000000..ccaa4dab --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/QuestionGenerator.java @@ -0,0 +1,18 @@ +package com.uniovi.components.generators; + +import com.uniovi.entities.Category; +import com.uniovi.entities.Question; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public interface QuestionGenerator { + + String getQuery(); + List getQuestions(); + + Category getCategory(); + + +} diff --git a/src/main/java/com/uniovi/components/generators/geography/AbstractGeographyGenerator.java b/src/main/java/com/uniovi/components/generators/geography/AbstractGeographyGenerator.java new file mode 100644 index 00000000..d01919e9 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/geography/AbstractGeographyGenerator.java @@ -0,0 +1,17 @@ +package com.uniovi.components.generators.geography; + +import com.uniovi.components.generators.AbstractQuestionGenerator; +import com.uniovi.entities.Category; +import com.uniovi.services.CategoryService; + +public abstract class AbstractGeographyGenerator extends AbstractQuestionGenerator { + + protected AbstractGeographyGenerator(CategoryService categoryService) { + super(categoryService); + } + + @Override + public Category getCategory() { + return categoryService.getCategoryByName("Geography"); + } +} diff --git a/src/main/java/com/uniovi/components/generators/geography/BorderQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/BorderQuestionGenerator.java new file mode 100644 index 00000000..1bbd4475 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/geography/BorderQuestionGenerator.java @@ -0,0 +1,70 @@ +package com.uniovi.components.generators.geography; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; + +import java.util.*; + +public class BorderQuestionGenerator extends AbstractGeographyGenerator{ + + private Set usedCountries = new HashSet<>(); + + public BorderQuestionGenerator(CategoryService categoryService) { + super(categoryService); + this.statement = "Which countries share a border with "; + } + + private List getAllBorderingCountries(JsonNode resultsNode, String correctCountry) { + List allBorderingCountries = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String borderingCountry = result.path("borderingCountryLabel").path("value").asText(); + if (!borderingCountry.equals(correctCountry)) { + allBorderingCountries.add(borderingCountry); + } + } + return allBorderingCountries; + } + + private List selectRandomIncorrectBorderingCountries(List allBorderingCountries, String correctCountry, int count) { + List incorrectBorderingCountries = new ArrayList<>(); + Random random = new Random(); + while (incorrectBorderingCountries.size() < count && allBorderingCountries.size() > 0) { + int randomIndex = random.nextInt(allBorderingCountries.size()); + String selectedBorderingCountry = allBorderingCountries.remove(randomIndex); + if (!selectedBorderingCountry.equals(correctCountry) && !incorrectBorderingCountries.contains(selectedBorderingCountry)) { + incorrectBorderingCountries.add(selectedBorderingCountry); + } + } + return incorrectBorderingCountries; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String borderingCountryLabel = result.path("borderingCountryLabel").path("value").asText(); + return selectRandomIncorrectBorderingCountries( + getAllBorderingCountries(results, borderingCountryLabel), + borderingCountryLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("borderingCountryLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("countryLabel").path("value").asText() + "?"; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?country ?countryLabel ?borderingCountry ?borderingCountryLabel\n" + + "WHERE {" + + " ?country wdt:P31 wd:Q3624078 ." + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + + " ?country wdt:P47 ?borderingCountry ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE],en\" }" + + "}"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/geography/CapitalQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/CapitalQuestionGenerator.java new file mode 100644 index 00000000..951292fc --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/geography/CapitalQuestionGenerator.java @@ -0,0 +1,72 @@ +package com.uniovi.components.generators.geography; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +@Component +public class CapitalQuestionGenerator extends AbstractGeographyGenerator{ + + public CapitalQuestionGenerator(CategoryService categoryService) { + super(categoryService); + this.statement = "What is the capital of "; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?country ?countryLabel ?capital ?capitalLabel\n" + + "WHERE {" + + " ?country wdt:P31 wd:Q3624078 ." + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + + " OPTIONAL { ?country wdt:P36 ?capital } ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE],en\" }" + + "}" + + "ORDER BY ?countryLabel"; + } + + private List getAllCapitals(JsonNode resultsNode, String correctCapital) { + // Obtener todas las capitales del JSON (distintas a la capital correcta) + List allCapitals = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String capital = result.path("capitalLabel").path("value").asText(); + if (!capital.equals(correctCapital)) { + allCapitals.add(capital); + } + } + return allCapitals; + } + + private List selectRandomIncorrectCapitals(List allCapitals, String correctCapital, int count) { + List incorrectCapitals = new ArrayList<>(); + Random random = new Random(); + while (incorrectCapitals.size() < count && allCapitals.size() > 0) { + int randomIndex = random.nextInt(allCapitals.size()); + String selectedCapital = allCapitals.remove(randomIndex); + if (!selectedCapital.equals(correctCapital) && !incorrectCapitals.contains(selectedCapital)) { + incorrectCapitals.add(selectedCapital); + } + } + return incorrectCapitals; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String capitalLabel = result.path("capitalLabel").path("value").asText(); + return selectRandomIncorrectCapitals(getAllCapitals(results, capitalLabel), capitalLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("capitalLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("countryLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/geography/ContinentQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/geography/ContinentQuestionGeneration.java new file mode 100644 index 00000000..6e89b66c --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/geography/ContinentQuestionGeneration.java @@ -0,0 +1,69 @@ +package com.uniovi.components.generators.geography; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class ContinentQuestionGeneration extends AbstractGeographyGenerator{ + public ContinentQuestionGeneration(CategoryService categoryService) { + super(categoryService); + this.statement = "In which continent is "; + } + + private List getAllContinents(JsonNode resultsNode, String correctContinent) { + // Obtener todas las capitales del JSON (distintas a la capital correcta) + List allContinents = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String continent = result.path("continentLabel").path("value").asText(); + if (!continent.equals(correctContinent)) { + allContinents.add(continent); + } + } + return allContinents; + } + + private List selectRandomIncorrectContinents(List allContinents, String correctContinent, int count) { + List incorrectContinents = new ArrayList<>(); + Random random = new Random(); + while (incorrectContinents.size() < count && allContinents.size() > 0) { + int randomIndex = random.nextInt(allContinents.size()); + String selectedCapital = allContinents.remove(randomIndex); + if (!selectedCapital.equals(correctContinent) && !incorrectContinents.contains(selectedCapital)) { + incorrectContinents.add(selectedCapital); + } + } + return incorrectContinents; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String continentLabel = result.path("continentLabel").path("value").asText(); + return selectRandomIncorrectContinents(getAllContinents(results, continentLabel), continentLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("continentLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("countryLabel").path("value").asText() + "?"; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?country ?countryLabel ?continent ?continentLabel\n" + + "WHERE {" + + " ?country wdt:P31 wd:Q3624078 " + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + + " OPTIONAL { ?country wdt:P30 ?continent } ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE],en\" }" + + "}" + + "ORDER BY ?countryLabel"; + } +} diff --git a/src/main/java/com/uniovi/dto/AnswerDto.java b/src/main/java/com/uniovi/dto/AnswerDto.java new file mode 100644 index 00000000..20ad1e37 --- /dev/null +++ b/src/main/java/com/uniovi/dto/AnswerDto.java @@ -0,0 +1,17 @@ +package com.uniovi.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class AnswerDto { + private Long id; + private String text; + private boolean correct; + +} diff --git a/src/main/java/com/uniovi/dto/CategoryDto.java b/src/main/java/com/uniovi/dto/CategoryDto.java new file mode 100644 index 00000000..6b34b07e --- /dev/null +++ b/src/main/java/com/uniovi/dto/CategoryDto.java @@ -0,0 +1,20 @@ +package com.uniovi.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class CategoryDto { + + private Long id; + private String name; + private String description; + private List questions; +} diff --git a/src/main/java/com/uniovi/dto/QuestionDto.java b/src/main/java/com/uniovi/dto/QuestionDto.java new file mode 100644 index 00000000..dac83779 --- /dev/null +++ b/src/main/java/com/uniovi/dto/QuestionDto.java @@ -0,0 +1,22 @@ +package com.uniovi.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class QuestionDto { + + private Long id; + private String statement; + private List options; + private AnswerDto correctAnswer; + private CategoryDto category; + +} diff --git a/src/main/java/com/uniovi/entities/Answer.java b/src/main/java/com/uniovi/entities/Answer.java new file mode 100644 index 00000000..61401b4a --- /dev/null +++ b/src/main/java/com/uniovi/entities/Answer.java @@ -0,0 +1,33 @@ +package com.uniovi.entities; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Entity +@NoArgsConstructor +public class Answer { + + @Id + @GeneratedValue + private Long id; + + private String text; + private boolean correct; + + @ManyToOne + private Question question; + + public Answer(String text, boolean correct) { + this.text = text; + this.correct = correct; + } + + public String toString() { + return text; + } + +} \ No newline at end of file diff --git a/src/main/java/com/uniovi/entities/Category.java b/src/main/java/com/uniovi/entities/Category.java new file mode 100644 index 00000000..cf5d8771 --- /dev/null +++ b/src/main/java/com/uniovi/entities/Category.java @@ -0,0 +1,32 @@ +package com.uniovi.entities; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.HashSet; +import java.util.Set; + +@Getter +@Setter +@Entity +@NoArgsConstructor +public class Category { + + @Id + @GeneratedValue + private Long id; + + @Column(unique = true) + private String name; + private String description; + + @OneToMany(mappedBy = "category") + private Set questions = new HashSet<>(); + + public Category(String name, String description) { + this.name = name; + this.description = description; + } +} diff --git a/src/main/java/com/uniovi/entities/Question.java b/src/main/java/com/uniovi/entities/Question.java new file mode 100644 index 00000000..5046a2b0 --- /dev/null +++ b/src/main/java/com/uniovi/entities/Question.java @@ -0,0 +1,94 @@ +package com.uniovi.entities; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.util.Assert; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +@Getter +@Setter +@Entity +@NoArgsConstructor +public class Question { + + @Id + @GeneratedValue + private Long id; + + @Column(unique = true) + private String statement; + + @OneToMany(mappedBy = "question") + private List options; + + @OneToOne + private Answer correctAnswer; + + @ManyToOne + private Category category; + + public Question(String statement, List options, Answer correctAnswer, Category category) { + Assert.isTrue(options.contains(correctAnswer), "Correct answer must be one of the options"); + this.statement = statement; + this.options = options; + this.correctAnswer = correctAnswer; + this.category = category; + } + + public void addOption(Answer option) { + options.add(option); + } + + public void removeOption(Answer option){ + options.remove(option); + } + + public Answer getOption(int index){ + return options.get(index); + } + + public Answer getOptions(String answer){ + for (Answer option : options) { + if (option.getText().equals(answer)) { + return option; + } + } + return null; + } + + public boolean isCorrectAnswer(Answer answer){ + return answer.isCorrect(); + } + + public void scrambleOptions(){ + Collections.shuffle(options); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Question question = (Question) o; + return Objects.equals(id, question.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "Question{" + + "statement='" + statement + '\'' + + ", options=" + options.toString() + + ", correctAnswer=" + correctAnswer.toString() + + ", category=" + category + + '}'; + } +} diff --git a/src/main/java/com/uniovi/repositories/AnswerRepository.java b/src/main/java/com/uniovi/repositories/AnswerRepository.java new file mode 100644 index 00000000..b0beb5f8 --- /dev/null +++ b/src/main/java/com/uniovi/repositories/AnswerRepository.java @@ -0,0 +1,12 @@ +package com.uniovi.repositories; + +import com.uniovi.entities.Answer; +import com.uniovi.entities.Question; +import org.springframework.data.repository.CrudRepository; + +import java.util.List; + +public interface AnswerRepository extends CrudRepository { + + List findByQuestion(Question question); +} diff --git a/src/main/java/com/uniovi/repositories/CategoryRepository.java b/src/main/java/com/uniovi/repositories/CategoryRepository.java new file mode 100644 index 00000000..2771d22f --- /dev/null +++ b/src/main/java/com/uniovi/repositories/CategoryRepository.java @@ -0,0 +1,10 @@ +package com.uniovi.repositories; + +import com.uniovi.entities.Category; +import org.springframework.data.repository.CrudRepository; + +public interface CategoryRepository extends CrudRepository { + + Category findByName(String name); + +} diff --git a/src/main/java/com/uniovi/repositories/QuestionRepository.java b/src/main/java/com/uniovi/repositories/QuestionRepository.java new file mode 100644 index 00000000..d940deac --- /dev/null +++ b/src/main/java/com/uniovi/repositories/QuestionRepository.java @@ -0,0 +1,9 @@ +package com.uniovi.repositories; + +import com.uniovi.entities.Question; +import org.springframework.data.repository.CrudRepository; + +import java.util.Optional; + +public interface QuestionRepository extends CrudRepository { +} diff --git a/src/main/java/com/uniovi/services/AnswerService.java b/src/main/java/com/uniovi/services/AnswerService.java new file mode 100644 index 00000000..ff2ddd44 --- /dev/null +++ b/src/main/java/com/uniovi/services/AnswerService.java @@ -0,0 +1,35 @@ +package com.uniovi.services; + +import com.uniovi.entities.Answer; +import com.uniovi.entities.Category; +import com.uniovi.entities.Question; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public interface AnswerService { + + /** + * Add a new answer to the database + * + * @param answer Question to be added + */ + void addNewAnswer(Answer answer); + + /** + * Get all the answers for a question + * + * @return A list with all the answers for a question + */ + List getAnswersPerQuestion(Question question); + + /** + * Get an answer by its id + * + * @param id The id of the answer + * @return The answer with the given id + */ + Optional getAnswer(Long id); +} diff --git a/src/main/java/com/uniovi/services/CategoryService.java b/src/main/java/com/uniovi/services/CategoryService.java new file mode 100644 index 00000000..52f29eb7 --- /dev/null +++ b/src/main/java/com/uniovi/services/CategoryService.java @@ -0,0 +1,36 @@ +package com.uniovi.services; + +import com.uniovi.entities.Category; +import com.uniovi.entities.Question; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public interface CategoryService { + + /** + * Add a new category to the database + * + * @param category Question to be added + */ + void addNewCategory(Category category); + + /** + * Get all the categories in the database + * + * @return A list with all the categories + */ + List getAllCategories(); + + /** + * Get a category by its id + * + * @param id The id of the category + * @return The category with the given id + */ + Optional getCategory(Long id); + + Category getCategoryByName(String geography); +} diff --git a/src/main/java/com/uniovi/services/QuestionService.java b/src/main/java/com/uniovi/services/QuestionService.java new file mode 100644 index 00000000..9bc96b7d --- /dev/null +++ b/src/main/java/com/uniovi/services/QuestionService.java @@ -0,0 +1,34 @@ +package com.uniovi.services; + +import com.uniovi.dto.QuestionDto; +import com.uniovi.entities.Question; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public interface QuestionService { + + /** + * Add a new question to the database + * + * @param question Question to be added + */ + void addNewQuestion(Question question); + + /** + * Get all the questions in the database + * + * @return A list with all the questions + */ + List getAllQuestions(); + + /** + * Get a question by its id + * + * @param id The id of the question + * @return The question with the given id + */ + Optional getQuestion(Long id); +} diff --git a/src/main/java/com/uniovi/services/impl/AnswerServiceImpl.java b/src/main/java/com/uniovi/services/impl/AnswerServiceImpl.java new file mode 100644 index 00000000..2bfdaa1d --- /dev/null +++ b/src/main/java/com/uniovi/services/impl/AnswerServiceImpl.java @@ -0,0 +1,35 @@ +package com.uniovi.services.impl; + +import com.uniovi.entities.Answer; +import com.uniovi.entities.Question; +import com.uniovi.repositories.AnswerRepository; +import com.uniovi.services.AnswerService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class AnswerServiceImpl implements AnswerService { + + private final AnswerRepository answerRepository; + + public AnswerServiceImpl(AnswerRepository answerRepository) { + this.answerRepository = answerRepository; + } + + @Override + public void addNewAnswer(Answer answer) { + answerRepository.save(answer); + } + + @Override + public List getAnswersPerQuestion(Question question) { + return answerRepository.findByQuestion(question); + } + + @Override + public Optional getAnswer(Long id) { + return answerRepository.findById(id); + } +} diff --git a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java new file mode 100644 index 00000000..636bffe5 --- /dev/null +++ b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java @@ -0,0 +1,55 @@ +package com.uniovi.services.impl; + +import com.uniovi.entities.Category; +import com.uniovi.repositories.CategoryRepository; +import com.uniovi.services.CategoryService; +import jakarta.annotation.PostConstruct; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Service +public class CategoryServiceImpl implements CategoryService { + + private final CategoryRepository categoryRepository; + + public CategoryServiceImpl(CategoryRepository categoryRepository) { + this.categoryRepository = categoryRepository; + } + + @Override + public void addNewCategory(Category category) { + categoryRepository.save(category); + } + + @Override + public List getAllCategories() { + List l = new ArrayList<>(); + categoryRepository.findAll().forEach(l::add); + return l; + } + + @Override + public Optional getCategory(Long id) { + return categoryRepository.findById(id); + } + + @Override + public Category getCategoryByName(String name) { + return categoryRepository.findByName(name); + } + + private static final Map.Entry[] CATEGORIES = new AbstractMap.SimpleEntry[] { + new AbstractMap.SimpleEntry<>("Geography", "Questions about geography") + }; + + @PostConstruct + public void init() { + // Add categories, ensuring there's only 1 of them always + for (Map.Entry category : CATEGORIES) { + if (categoryRepository.findByName(category.getKey())==null) { + addNewCategory(new Category(category.getKey(), category.getValue())); + } + } + } +} diff --git a/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java b/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java new file mode 100644 index 00000000..0a3aa771 --- /dev/null +++ b/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java @@ -0,0 +1,38 @@ +package com.uniovi.services.impl; + +import com.uniovi.entities.Question; +import com.uniovi.repositories.QuestionRepository; +import com.uniovi.services.QuestionService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Service +public class QuestionServiceImpl implements QuestionService { + + private final QuestionRepository questionRepository; + + public QuestionServiceImpl(QuestionRepository questionRepository) { + this.questionRepository = questionRepository; + } + + @Override + public void addNewQuestion(Question question) { + questionRepository.save(question); + } + + @Override + public List getAllQuestions() { + List l = new ArrayList<>(); + questionRepository.findAll().forEach(l::add); + return l; + } + + @Override + public Optional getQuestion(Long id) { + return questionRepository.findById(id); + } + +}