diff --git a/pom.xml b/pom.xml
index ff89545..46b5f08 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,13 +25,16 @@
com.h2database
h2
- runtime
org.springframework.boot
spring-boot-starter-test
test
+
+ org.projectlombok
+ lombok
+
diff --git a/src/main/java/com/opinionowl/opinionowl/OpinionOwlApplication.java b/src/main/java/com/opinionowl/opinionowl/OpinionOwlApplication.java
index c89dc91..1053dfc 100644
--- a/src/main/java/com/opinionowl/opinionowl/OpinionOwlApplication.java
+++ b/src/main/java/com/opinionowl/opinionowl/OpinionOwlApplication.java
@@ -3,6 +3,9 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+/**
+ * The starting point for the application.
+ */
@SpringBootApplication
public class OpinionOwlApplication {
diff --git a/src/main/java/com/opinionowl/opinionowl/models/Answer.java b/src/main/java/com/opinionowl/opinionowl/models/Answer.java
new file mode 100644
index 0000000..7c4f7b7
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/models/Answer.java
@@ -0,0 +1,51 @@
+package com.opinionowl.opinionowl.models;
+
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * The class in charge of holding the indivdual answers for each response.
+ */
+@Entity
+@Getter
+@Setter
+@NoArgsConstructor
+public class Answer {
+ // The id of the answer.
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ // The response which the answer belongs to.
+ @ManyToOne
+ private Response response;
+
+ // The id of the question.
+ private Long question;
+
+ // The contents of the response.
+ private String content;
+
+ /**
+ * The constructor for answer.
+ * @param response the response for which the answe belongs to.
+ * @param question the question id.
+ * @param content the content of the reply.
+ */
+ public Answer(Response response, Long question, String content){
+ this.response = response;
+ this.question = question;
+ this.content = content;
+ }
+
+ /**
+ * @return the answer in string form.
+ */
+ @Override
+ public String toString(){
+ return "Answer#" + id + " value:" + content;
+ }
+
+}
diff --git a/src/main/java/com/opinionowl/opinionowl/models/LongAnswerQuestion.java b/src/main/java/com/opinionowl/opinionowl/models/LongAnswerQuestion.java
new file mode 100644
index 0000000..95c049f
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/models/LongAnswerQuestion.java
@@ -0,0 +1,42 @@
+package com.opinionowl.opinionowl.models;
+
+import jakarta.persistence.Entity;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * The class used to describe the long answer questions.
+ */
+@Entity
+@Getter
+@Setter
+public class LongAnswerQuestion extends Question{
+ // The character limit for the question.
+ private int charLimit;
+
+ /**
+ * The default constructor for the class.
+ */
+ public LongAnswerQuestion(){
+ this("", 0);
+ }
+
+ /**
+ * The constructor for the class.
+ * @param prompt the prompt for the question
+ * @param charLimit the character limit for the response.
+ */
+ public LongAnswerQuestion(String prompt, int charLimit){
+ super(prompt, QuestionType.LONG_ANSWER);
+ this.charLimit = charLimit;
+ }
+
+ /**
+ * @return the question in string form.
+ */
+ @Override
+ public String toString(){
+ return super.toString() + " charLimit:" + charLimit;
+ }
+
+}
diff --git a/src/main/java/com/opinionowl/opinionowl/models/Question.java b/src/main/java/com/opinionowl/opinionowl/models/Question.java
new file mode 100644
index 0000000..436edc5
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/models/Question.java
@@ -0,0 +1,45 @@
+package com.opinionowl.opinionowl.models;
+
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.NoArgsConstructor;
+
+/**
+ * The Question class which keeps track of the survey questions.
+ */
+@Entity
+@Getter
+@Setter
+@NoArgsConstructor
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class Question {
+ // The id of the question.
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ // The prompt for the question.
+ private String prompt;
+
+ // The type of the question.
+ private QuestionType type;
+
+ /**
+ * The constructor for the question class.
+ * @param prompt the prompt for the question.
+ * @param type the type of the question
+ */
+ public Question(String prompt, QuestionType type){
+ this.prompt = prompt;
+ this.type = type;
+ }
+
+ /**
+ * @return the question in string form.
+ */
+ @Override
+ public String toString(){
+ return "Question id:" + id + " prompt:" + prompt;
+ }
+}
diff --git a/src/main/java/com/opinionowl/opinionowl/models/QuestionType.java b/src/main/java/com/opinionowl/opinionowl/models/QuestionType.java
new file mode 100644
index 0000000..b655f43
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/models/QuestionType.java
@@ -0,0 +1,10 @@
+package com.opinionowl.opinionowl.models;
+
+/**
+ * An Enum to keep track of the different question types.
+ */
+public enum QuestionType {
+ LONG_ANSWER,
+ RADIO_CHOICE,
+ RANGE
+}
diff --git a/src/main/java/com/opinionowl/opinionowl/models/RadioChoiceQuestion.java b/src/main/java/com/opinionowl/opinionowl/models/RadioChoiceQuestion.java
new file mode 100644
index 0000000..f167c20
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/models/RadioChoiceQuestion.java
@@ -0,0 +1,49 @@
+package com.opinionowl.opinionowl.models;
+
+import jakarta.persistence.Entity;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * The class used to describe the multiple choice questions.
+ */
+@Entity
+@Getter
+@Setter
+public class RadioChoiceQuestion extends Question {
+ // The choices for the question.
+ private String[] choices;
+
+ /**
+ * The default constructor for the class.
+ */
+ public RadioChoiceQuestion() {
+ this("", new String[0]);
+ }
+
+ /**
+ * The constructor for the class.
+ * @param prompt the prompt for the question.
+ * @param choices the choices for the question.
+ */
+ public RadioChoiceQuestion(String prompt, String[] choices){
+ super(prompt, QuestionType.RADIO_CHOICE);
+ this.choices = choices;
+ }
+
+ /**
+ * @return the question in string form.
+ */
+ @Override
+ public String toString(){
+ String res = super.toString() + " choices:[";
+ if (choices.length > 0) {
+ for (int i = 0; i < choices.length - 1; i++){
+ res += choices[i] + ", ";
+ }
+ res += choices[choices.length - 1];
+ }
+ res += "]";
+ return res;
+ }
+}
diff --git a/src/main/java/com/opinionowl/opinionowl/models/RangeQuestion.java b/src/main/java/com/opinionowl/opinionowl/models/RangeQuestion.java
new file mode 100644
index 0000000..6bcdc47
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/models/RangeQuestion.java
@@ -0,0 +1,61 @@
+package com.opinionowl.opinionowl.models;
+
+import jakarta.persistence.Entity;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * The class used to describe the range questions.
+ */
+@Entity
+@Getter
+@Setter
+public class RangeQuestion extends Question {
+ // The lower value for the range.
+ int lower;
+
+ // the upper value for the range.
+ int upper;
+
+ // the increment the range.
+ int increment;
+
+ /**
+ * The default constructor for the class.
+ */
+ public RangeQuestion(){
+ this("", 0, 0);
+ }
+
+ /**
+ * The constructor for the class without increment.
+ * @param prompt the prompt for the question.
+ * @param lower the lower value for the range.
+ * @param upper the upper value for the range.
+ */
+ public RangeQuestion(String prompt, int lower, int upper){
+ this(prompt, lower, upper, 1);
+ }
+
+ /**
+ * The constructor for the class with increment.
+ * @param prompt the prompt for the question.
+ * @param lower the lower value for the range.
+ * @param upper the upper value for the range.
+ * @param increment the increment value for the range.
+ */
+ public RangeQuestion(String prompt, int lower, int upper, int increment){
+ super(prompt, QuestionType.RANGE);
+ this.lower = lower;
+ this.upper = upper;
+ this.increment = increment;
+ }
+
+ /**
+ * @return the question in string form.
+ */
+ @Override
+ public String toString(){
+ return super.toString() + " lower:" + lower + " upper:" + upper + " increment:" + increment;
+ }
+}
diff --git a/src/main/java/com/opinionowl/opinionowl/models/Response.java b/src/main/java/com/opinionowl/opinionowl/models/Response.java
new file mode 100644
index 0000000..d5d92d1
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/models/Response.java
@@ -0,0 +1,56 @@
+package com.opinionowl.opinionowl.models;
+
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The Response class in charge holding the survey response.
+ */
+@Entity
+@Getter
+@Setter
+@NoArgsConstructor
+public class Response {
+ // The id of the response.
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ // The survey object used for the response.
+ @ManyToOne
+ private Survey survey;
+
+ // The list of the questions for the response.
+ @OneToMany(mappedBy = "response", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
+ private List answers;
+
+ /**
+ * The constructor for the Response class.
+ */
+ public Response(Survey survey) {
+ this.survey = survey;
+ this.answers = new ArrayList<>();
+ }
+
+ /**
+ * Adds an answer to the survey.
+ * @param question the question id.
+ * @param content the content of the reply.
+ */
+ public void addAnswer(Long question, String content){
+ this.answers.add(new Answer(this, question, content));
+ }
+
+ /**
+ * @return the Response class in string form.
+ */
+ @Override
+ public String toString(){
+ return "Response #" + id + " answers:" + answers;
+ }
+}
diff --git a/src/main/java/com/opinionowl/opinionowl/models/Survey.java b/src/main/java/com/opinionowl/opinionowl/models/Survey.java
new file mode 100644
index 0000000..349f7d8
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/models/Survey.java
@@ -0,0 +1,127 @@
+package com.opinionowl.opinionowl.models;
+
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The survey class which contains all the information needed to create survey.
+ */
+@Entity
+@Getter
+@Setter
+@NoArgsConstructor
+public class Survey {
+ // Keeps track of the Id of the survey.
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ // Keeps track of the questions of the survey.
+ @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+ private List questions;
+
+ // Keeps track of the survey responses.
+ @OneToMany(mappedBy = "survey", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
+ private List responses;
+
+ // Keeps track of whether the survey is open or closed.
+ private boolean closed;
+
+ // The title for the survey.
+ private String title;
+
+ /**
+ * The default constructor for the survey.
+ */
+ public Survey(String title){
+ this.title = title;
+ this.questions = new ArrayList<>();
+ this.responses = new ArrayList<>();
+ this.closed = false;
+ }
+
+ /**
+ * Adds a question to the survey.
+ *
+ * @param question the question to add to the survey.
+ */
+ public boolean addQuestion(Question question){
+ if (!closed) {
+ this.questions.add(question);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Removes a question from the survey.
+ * @param questionId the Id of the question.
+ * @return true if successfully removed the question, false otherwise.
+ */
+ public boolean removeQuestion(Long questionId){
+ if (!closed) {
+ return this.questions.removeIf(q -> q.getId() == questionId);
+ }
+ return false;
+ }
+
+ /**
+ * Adds a response to the survey.
+ * @param response the response to add to the survey.
+ */
+ public boolean addResponse(Response response){
+ if (!closed){
+ this.responses.add(response);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Removes the response from the survey.
+ * @param responseId the id of the response to remove.
+ * @return true if successfully remove, false otherwise.
+ */
+ public boolean removeResponse(Long responseId){
+ return this.responses.removeIf(r -> r.getId() == responseId);
+ }
+
+ /**
+ * Returns a list of response for a specific question.
+ * @param questionId the id of the question.
+ * @return a list of the responses for that question.
+ */
+ public List getResponsesForQuestion(Long questionId){
+ List result = new ArrayList<>();
+ for (Response r: responses){
+ for (Answer a: r.getAnswers()){
+ if (a.getQuestion() == questionId){
+ result.add(a.getContent());
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @return the survey in string form.
+ */
+ @Override
+ public String toString(){
+ String res = "Survey#" + id + " Title:" + title + " Closed?" + closed;
+ res += "\n-----Questions-----";
+ for (Question q: questions){
+ res += "\n" + q.toString();
+ }
+ res += "\n-----Response-----";
+ for (Response r: responses){
+ res += "\n" + r.toString();
+ }
+ return res;
+ }
+}
diff --git a/src/main/java/com/opinionowl/opinionowl/repos/AnswerRepository.java b/src/main/java/com/opinionowl/opinionowl/repos/AnswerRepository.java
new file mode 100644
index 0000000..9054318
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/repos/AnswerRepository.java
@@ -0,0 +1,14 @@
+package com.opinionowl.opinionowl.repos;
+
+import com.opinionowl.opinionowl.models.Answer;
+import org.springframework.data.repository.CrudRepository;
+
+import java.util.List;
+
+/**
+ * The repository in charge of managing the CRUD operations for Answer Entity.
+ */
+public interface AnswerRepository extends CrudRepository {
+ // Essentially performs SELECT * FROM answer
+ List findAll();
+}
diff --git a/src/main/java/com/opinionowl/opinionowl/repos/QuestionRepository.java b/src/main/java/com/opinionowl/opinionowl/repos/QuestionRepository.java
new file mode 100644
index 0000000..5dce970
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/repos/QuestionRepository.java
@@ -0,0 +1,14 @@
+package com.opinionowl.opinionowl.repos;
+
+import com.opinionowl.opinionowl.models.Question;
+import org.springframework.data.repository.CrudRepository;
+
+import java.util.List;
+
+/**
+ * The repository in charge of managing the CRUD operations for Question Entity.
+ */
+public interface QuestionRepository extends CrudRepository {
+ // Essentially performs SELECT * FROM question
+ List findAll();
+}
diff --git a/src/main/java/com/opinionowl/opinionowl/repos/ResponseRepository.java b/src/main/java/com/opinionowl/opinionowl/repos/ResponseRepository.java
new file mode 100644
index 0000000..7d623b7
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/repos/ResponseRepository.java
@@ -0,0 +1,14 @@
+package com.opinionowl.opinionowl.repos;
+
+import com.opinionowl.opinionowl.models.Response;
+import org.springframework.data.repository.CrudRepository;
+
+import java.util.List;
+
+/**
+ * The repository in charge of managing the CRUD operations for Response Entity.
+ */
+public interface ResponseRepository extends CrudRepository {
+ // Essentially performs SELECT * FROM response
+ List findAll();
+}
diff --git a/src/main/java/com/opinionowl/opinionowl/repos/SurveyRepository.java b/src/main/java/com/opinionowl/opinionowl/repos/SurveyRepository.java
new file mode 100644
index 0000000..99c686f
--- /dev/null
+++ b/src/main/java/com/opinionowl/opinionowl/repos/SurveyRepository.java
@@ -0,0 +1,14 @@
+package com.opinionowl.opinionowl.repos;
+
+import com.opinionowl.opinionowl.models.Survey;
+import org.springframework.data.repository.CrudRepository;
+
+import java.util.List;
+
+/**
+ * The repository in charge of managing the CRUD operations for Survey Entity.
+ */
+public interface SurveyRepository extends CrudRepository {
+ // Essentially performs SELECT * FROM survey
+ List findAll();
+}
diff --git a/src/test/java/com/opinionowl/opinionowl/SurveyTest.java b/src/test/java/com/opinionowl/opinionowl/SurveyTest.java
new file mode 100644
index 0000000..ef77739
--- /dev/null
+++ b/src/test/java/com/opinionowl/opinionowl/SurveyTest.java
@@ -0,0 +1,59 @@
+package com.opinionowl.opinionowl;
+
+import com.opinionowl.opinionowl.models.*;
+import com.opinionowl.opinionowl.repos.SurveyRepository;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.List;
+
+@SpringBootTest
+public class SurveyTest {
+ @Autowired
+ private SurveyRepository surveyRepository;
+
+ @Test
+ public void testPersist() {
+ Survey survey = new Survey("TEST_SURVEY");
+ LongAnswerQuestion q1 = new LongAnswerQuestion("test1", 2);
+ RadioChoiceQuestion q2 = new RadioChoiceQuestion("test2", new String[]{"a", "c", "d"});
+ RangeQuestion q3 = new RangeQuestion("test3", 1, 10);
+
+ survey.addQuestion(q1);
+ survey.addQuestion(q2);
+ survey.addQuestion(q3);
+
+ surveyRepository.save(survey);
+
+ Response r1 = new Response(survey);
+
+ r1.addAnswer(q1.getId(), "hi");
+ r1.addAnswer(q2.getId(), "b");
+
+ survey.addResponse(r1);
+
+ surveyRepository.save(survey);
+
+ survey.setClosed(true);
+
+ Response r2 = new Response(survey);
+
+ r2.addAnswer(q1.getId(), "yo");
+ r2.addAnswer(q2.getId(), "a");
+
+ surveyRepository.save(survey);
+
+ List results = surveyRepository.findAll();
+ for (Survey r : results){
+ System.out.println(r.toString());
+
+ for (Question q : r.getQuestions()){
+ if (q.getType() == QuestionType.LONG_ANSWER){
+ LongAnswerQuestion laq = (LongAnswerQuestion) q;
+ System.out.println(laq.getCharLimit());
+ }
+ }
+ }
+ }
+}