Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API routes and basic HTML templates added #10

Merged
merged 12 commits into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,20 @@
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand Down
116 changes: 116 additions & 0 deletions src/main/java/com/opinionowl/opinionowl/controllers/APIController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package com.opinionowl.opinionowl.controllers;
import com.fasterxml.jackson.databind.ObjectMapper; // You might need to import this class

import com.opinionowl.opinionowl.models.*;
import com.opinionowl.opinionowl.repos.SurveyRepository;
import com.opinionowl.opinionowl.repos.UserRepository;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.fasterxml.jackson.core.type.TypeReference;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;

/**
* Version 1 of the API layer for Opinion Owl
*/
@RestController
@RequestMapping("/api/v1")
@NoArgsConstructor
public class APIController {

@Autowired
SurveyRepository surveyRepo;


@Autowired
private UserRepository userRepository;


/**
* <p>Api call to handle the survey answers by a user.</p>
* <br />
* <strong>Api route: api/v1/postSurveyResponses</strong>
* @param response HttpServletResponse server side response
* @throws IOException
*/
@PostMapping("/postSurveyResponses")
public void postSurveyResponses(HttpServletResponse response) throws IOException {
// handle save of survey data
// redirect to home
response.sendRedirect("/");
}

/**
* <p>API Call to post a generated survey by the user. A survey generated JSON is required from the client</p>
* <br />
* <strong>Example of a JSON:</strong>
* <pre>
* json = {
* title: "title",
* textQuestions: ["question 1", "question 2"],
* radioQuestions: {
* "question 1": ["radio 1", "radio 2"],
* "question 2": ["radio 1", "radio 2", "radio 3"]
* },
* numericRanges: {
* "question 1": [1, 11],
* "question 2": [1, 5]
* }
* }
* </pre>
* @param request HttpServletRequest request from the client
* @return 200 if api was a success
* @throws IOException
*/
@PostMapping("/createSurvey")
public int createSurvey(HttpServletRequest request) throws IOException {
System.out.println("createSurvey() API");
// read the json sent by the client
BufferedReader reader = request.getReader();
// create a string format of the json from the reader
StringBuilder jsonBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
jsonBuilder.append(line);
}
String jsonData = jsonBuilder.toString();
System.out.println("JSONDATA: " + jsonData);
// Parse the JSON data using Jackson ObjectMapper

//create the objects as java objects
ObjectMapper objectMapper = new ObjectMapper();
HashMap<String, Object> surveyData = objectMapper.readValue(jsonData, new TypeReference<HashMap<String, Object>>() {});
// Extract specific data from the parsed JSON
String title = (String) surveyData.get("title");
List<String> textQuestions = (List<String>) surveyData.get("textQuestions");
HashMap<String, List<String>> radioQuestions = (HashMap<String, List<String>>) surveyData.get("radioQuestions");
HashMap<String, List<Integer>> numericRanges = (HashMap<String, List<Integer>>) surveyData.get("numericRanges");

AppUser user = new AppUser("username", "password");
userRepository.save(user);
Survey survey = new Survey(user, title);
user.addSurvey(survey);
// add all the question types to the survey
for (String questionTitle : textQuestions) {
survey.addQuestion(new LongAnswerQuestion(survey, questionTitle, 50));
}

for (String questionTitle : radioQuestions.keySet()) {
String[] radioQuestionsArr = new String[radioQuestions.get(questionTitle).size()];
survey.addQuestion(new RadioChoiceQuestion(survey, questionTitle, radioQuestions.get(questionTitle).toArray(radioQuestionsArr)));
}

for (String questionTitle : numericRanges.keySet()) {
List<Integer> ranges = numericRanges.get(questionTitle);
survey.addQuestion(new RangeQuestion(survey, questionTitle, ranges.get(0), ranges.get(1), 1));
}
surveyRepo.save(survey);
System.out.println("survey generated\n\n" + survey);
return 200;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.opinionowl.opinionowl.controllers;

import com.opinionowl.opinionowl.models.*;
import com.opinionowl.opinionowl.repos.SurveyRepository;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;

/**
* Route controller for Opinion Owl pages
*/
@Controller
@NoArgsConstructor
public class PageController {

@Autowired
SurveyRepository surveyRepo;

/**
* <p>Home route that gets all the surveys in the database, sends it to the model and directs the user to the home page</p>
* @param model Model, the client Model
* @return String, the html template
*/
@GetMapping("/")
public String getHomePage(Model model) {
List<Survey> surveys = surveyRepo.findAll();
model.addAttribute("surveys", surveys);
return "index";
}

/**
* <p>Route for the create survey page</p>
* @param model Model, the client Model
* @return String ,the html template
*/
@GetMapping("/createSurvey")
public String getCreateSurveyPage(Model model) {
return "createSurvey";
}

/**
* <p>Route to direct the client to the answer survey page, given a survey id to pass the Survey object to the Model</p>
* <br />
* <strong>Example call: /answerSurvey?surveyId=1</strong>
* @param surveyId Long, the ID associated with a survey
* @param model Model, the client Model
* @return String, the html template
*/
@GetMapping("/answerSurvey")
public String getAnswerSurveyPage(@RequestParam(value = "surveyId") Long surveyId, Model model) {
// find the survey by id
Optional<Survey> surveyO = surveyRepo.findById(surveyId);
if (surveyO.isPresent()) {
// was able to obtain a survey from the database by id, and grab it from the Optional Object
Survey survey = surveyO.get();
System.out.println("Survey found:");
System.out.println(survey);
// cast the order of the questions to the associtate subclass they belong to
// Cast in hashmaps as <question#, Question>
List<Question> q = survey.getQuestions();
HashMap<Integer, LongAnswerQuestion> longAnswerQuestions = new HashMap<>();
HashMap<Integer, RadioChoiceQuestion> radioChoiceQuestions = new HashMap<>();
HashMap<Integer, RangeQuestion> rangeQuestionQuestions = new HashMap<>();
int numQuestions = q.size();
String title = survey.getTitle();
for (int i = 0; i<numQuestions; i++) {
Question question = q.get(i);
int questionNumber = i + 1;
if (question.getType() == QuestionType.LONG_ANSWER) {
longAnswerQuestions.put(questionNumber, (LongAnswerQuestion) question);
} else if (question.getType() == QuestionType.RADIO_CHOICE) {
radioChoiceQuestions.put(questionNumber, (RadioChoiceQuestion) question);
} else if (question.getType() == QuestionType.RANGE) {
rangeQuestionQuestions.put(questionNumber, (RangeQuestion) question);
}
}
// send the Model the data necessary for the page
model.addAttribute("surveyId", survey.getId());
model.addAttribute("surveyTitle", title);
model.addAttribute("numberOfQuestions", numQuestions);
model.addAttribute("longAnswerQuestions", longAnswerQuestions);
model.addAttribute("radioChoiceQuestions", radioChoiceQuestions);
model.addAttribute("rangeQuestionQuestions", rangeQuestionQuestions);
} else {
// could not find survey, Error
// TODO: Redirect the user to a Error boundary page, or maybe the home page instead with a Toast message
System.out.println("ERROR: Survey could not be found");
System.exit(1);
}
return "answerSurvey";
}

@GetMapping("/viewResponse")
public String getViewResponsePage(Model model) {
return "viewResponse";
}
}
15 changes: 12 additions & 3 deletions src/main/java/com/opinionowl/opinionowl/models/QuestionType.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
package com.opinionowl.opinionowl.models;

import lombok.Getter;

/**
* An Enum to keep track of the different question types.
*/

@Getter
public enum QuestionType {
LONG_ANSWER,
RADIO_CHOICE,
RANGE
LONG_ANSWER("Long Answer"),
RADIO_CHOICE("Radio Choice"),
RANGE("Range");

private final String type;
QuestionType(String type) {
this.type = type;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
import org.springframework.data.repository.CrudRepository;

import java.util.List;
import java.util.Optional;

/**
* The repository in charge of managing the CRUD operations for Survey Entity.
*/
public interface SurveyRepository extends CrudRepository<Survey, Long> {
// Essentially performs SELECT * FROM survey
List<Survey> findAll();

Survey findById(long Id);
}
3 changes: 2 additions & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@

spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
Binary file added src/main/resources/static/images/owl.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading