Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ public class Assignment {
@Column()
private int maxPoints;

@Column()
private boolean quiz;

@Column()
private int jointId;

/* HashMap is used to store JSON for daily "stats"
"stats": {
"2022-11-13": {
Expand All @@ -45,10 +51,13 @@ public class Assignment {
@Column(columnDefinition = "jsonb")
private Map<String,Map<String, Object>> submissions = new HashMap<>();

public Assignment(String title, String desc, String link, int maxPoints) {
public Assignment(String title, String desc, String link, int maxPoints, int jointId) {
this.title = title;
this.desc = desc;
this.link = link;
this.maxPoints = maxPoints;
this.quiz = false;
this.jointId = jointId;
//this.id = id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
Expand All @@ -24,26 +24,32 @@ public class AssignmentApiController {

// Autowired enables Control to connect URI request and POJO Object to easily for Database CRUD operations
@Autowired
private AssignmentJpaRepository repository;
private AssignmentJpaRepository assignmentRepository;

@Autowired
private QuizJpaRepository quizRepository;

@Autowired
private GradeJpaRepository gradeRepository;


/* GET List of Jokes
* @GetMapping annotation is used for mapping HTTP GET requests onto specific handler methods.
*/
int idCount = 1; //Needed to prevent id overlap with quizzes and assignments

@CrossOrigin(origins = "*", allowedHeaders = "*")
@GetMapping("/")
public ResponseEntity<List<Assignment>> getJokes() {
// ResponseEntity returns List of Jokes provide by JPA findAll()
return new ResponseEntity<>( repository.findAll(), HttpStatus.OK);
public ResponseEntity<List<Object>> getRepositories() {
List<Object> combined = new ArrayList<>();
combined.addAll(assignmentRepository.findAll());
combined.addAll(quizRepository.findAll());
return new ResponseEntity<>(combined, HttpStatus.OK);
}



@CrossOrigin(origins = "*", allowedHeaders = "*")
@GetMapping("/{id}")
public ResponseEntity<Assignment> getById(@PathVariable Long id) {
Optional<Assignment> assignmentOptional = repository.findById(id);
Optional<Assignment> assignmentOptional = assignmentRepository.findById(id);

return assignmentOptional.map(assignment -> new ResponseEntity<>(assignment, HttpStatus.OK))
.orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
Expand All @@ -69,22 +75,83 @@ public ResponseEntity<Object> postPerson(
return new ResponseEntity<>("maxPoints must be positive", HttpStatus.BAD_REQUEST);
}

repository.save(new Assignment(title, desc, link, maxPoints));
assignmentRepository.save(new Assignment(title, desc, link, maxPoints, idCount));
idCount++;
return new ResponseEntity<>("Created successfully", HttpStatus.CREATED);
}

@CrossOrigin(origins = "*", allowedHeaders = "*")
@PostMapping("/postQuiz")
public ResponseEntity<Object> postQuiz(
@RequestParam("title") String title,
@RequestParam("desc") String desc,
@RequestParam("maxPoints") int maxPoints,
@RequestBody final Map<String,Object> questions) {
if(title.length() < 3 || title.length() > 100) {
return new ResponseEntity<>("Title is less than 3 or longer than 100 characters", HttpStatus.BAD_REQUEST);
}
if(desc.length() < 3 || desc.length() > 50000) {
return new ResponseEntity<>("Desc is less than 3 or longer than 500000 characters", HttpStatus.BAD_REQUEST);
}
if(maxPoints <= 0) {
return new ResponseEntity<>("maxPoints must be positive", HttpStatus.BAD_REQUEST);
}

//Check Questions
// Extract Attributes from JSON

Map<String, Object> attributeMap = new HashMap<>();
int questionNum = 1;
for (Map.Entry<String,Object> questionTemp : questions.entrySet()) {
if (!(questionTemp.getValue() instanceof HashMap)) {
return new ResponseEntity<>("Questions should contain hashmaps", HttpStatus.BAD_REQUEST);
}
Map<String, Object> question = ((Map<String, Object>)questionTemp.getValue());

Map<String, Object> subAttributeMap = new HashMap<>();


for (Map.Entry<String,Object> attribute : question.entrySet()) {
if(attribute.getKey().equals("answers"))
if (attribute.getValue() instanceof List) {
subAttributeMap.put(attribute.getKey(), attribute.getValue());
} else {
return new ResponseEntity<>("Answers attribute should be a list", HttpStatus.BAD_REQUEST);
}

if(attribute.getKey().equals("correctAnswer"))
subAttributeMap.put(attribute.getKey(), attribute.getValue());

if(attribute.getKey().equals("desc"))
subAttributeMap.put(attribute.getKey(), attribute.getValue());

}
//Does it have all attributes?
if(!(subAttributeMap.containsKey("answers") && subAttributeMap.containsKey("correctAnswer") && subAttributeMap.containsKey("desc"))) {
return new ResponseEntity<>("Missing attributes for question #" + questionNum + "answers, correctAnswer, and desc are required: " + subAttributeMap, HttpStatus.BAD_REQUEST);
}

//Add question data to main attribute map
attributeMap.put(Integer.toString(questionNum), subAttributeMap);
questionNum++;
}

quizRepository.save(new Quiz(title, desc, maxPoints, idCount, attributeMap));
idCount++;
return new ResponseEntity<>("Created successfully", HttpStatus.CREATED);
}
/* Update Like
* @PutMapping annotation is used for mapping HTTP PUT requests onto specific handler methods.
* @PathVariable annotation extracts the templated part {id}, from the URI
*/

@PostMapping(value = "/submit", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> personStats(@RequestBody final Map<String,Object> request_map) {
// find ID
if (!(request_map.get("id") instanceof String)){
return new ResponseEntity<>("id should be a String", HttpStatus.BAD_REQUEST);
}
long id=Long.parseLong((String)request_map.get("id"));
Optional<Assignment> optional = repository.findById((id));
int id=Integer.parseInt((String)request_map.get("id"));

List<Assignment> assignments = assignmentRepository.findByJointId(id);
Optional<Assignment> optional = assignments.isEmpty() ? Optional.empty() : Optional.of(assignments.get(0));

if (optional.isPresent()) { // Good ID
Assignment assignment = optional.get(); // value from findByID

Expand All @@ -93,35 +160,25 @@ public ResponseEntity<Object> personStats(@RequestBody final Map<String,Object>
for (Map.Entry<String,Object> submission : request_map.entrySet()) {
// Add needed attributes to attributeMap

if(submission.getKey().equals("contributors"))
if(submission.getKey().equals("answers"))
if (submission.getValue() instanceof List) {
attributeMap.put(submission.getKey(), submission.getValue());
} else {
return new ResponseEntity<>("Contributors attribute should be a list", HttpStatus.BAD_REQUEST);
}

if(submission.getKey().equals("title"))
attributeMap.put(submission.getKey(), submission.getValue());

if(submission.getKey().equals("desc"))
attributeMap.put(submission.getKey(), submission.getValue());

if(submission.getKey().equals("link"))
attributeMap.put(submission.getKey(), submission.getValue());

}

//Does it have all attributes?
if(!(attributeMap.containsKey("contributors") && attributeMap.containsKey("title") && attributeMap.containsKey("desc") && attributeMap.containsKey("link"))) {
return new ResponseEntity<>("Missing attributes. username, contributors, title, desc, and link are required" + attributeMap, HttpStatus.BAD_REQUEST);
if(!(attributeMap.containsKey("answers") && attributeMap.containsKey("username"))) {
return new ResponseEntity<>("Missing attributes. username and answers are required" + attributeMap, HttpStatus.BAD_REQUEST);
}

// Set Date and Attributes to SQL HashMap
Map<String, Map<String, Object>> date_map = assignment.getSubmissions();
date_map.put( (String) request_map.get("username"), attributeMap );
date_map.put( (String) request_map.get("username"), attributeMap);

assignment.setSubmissions(date_map);
repository.save(assignment);
assignmentRepository.save(assignment);

//Save grade as well for each contributor
List<String> contributors = (List<String>) attributeMap.get("contributors");
Expand All @@ -135,6 +192,65 @@ public ResponseEntity<Object> personStats(@RequestBody final Map<String,Object>
// return Person with update Stats
return new ResponseEntity<>(assignment, HttpStatus.OK);
}

//Check for quiz

List<Quiz> quizzes = quizRepository.findByJointId(id);
Optional<Quiz> optional2 = quizzes.isEmpty() ? Optional.empty() : Optional.of(quizzes.get(0));

if (optional2.isPresent()) { // Good ID
Quiz quiz = optional2.get(); // value from findByID

// Extract Attributes from JSON
Map<String, Object> attributeMap = new HashMap<>();
for (Map.Entry<String,Object> submission : request_map.entrySet()) {
// Add needed attributes to attributeMap

if(submission.getKey().equals("answers"))
if (submission.getValue() instanceof List) {
attributeMap.put(submission.getKey(), submission.getValue());
} else {
return new ResponseEntity<>("Contributors attribute should be a list", HttpStatus.BAD_REQUEST);
}

if(submission.getKey().equals("username"))
attributeMap.put(submission.getKey(), submission.getValue());
}

//Does it have all attributes?
if(!(attributeMap.containsKey("answers") && attributeMap.containsKey("username"))) {
return new ResponseEntity<>("Missing attributes. username and answers are required" + attributeMap, HttpStatus.BAD_REQUEST);
}

// Set Date and Attributes to SQL HashMap
Map<String, Map<String, Object>> date_map = quiz.getSubmissions();
date_map.put( (String) request_map.get("username"), attributeMap );

quiz.setSubmissions(date_map);
quizRepository.save(quiz);

//Grade it
/*ArrayList<Integer> submittedAnswers = (ArrayList<Integer>)attributeMap.get("answers");
Map<String, Object> questions = quizRepository.getById(Long.parseLong(Integer.toString(id))).getQuestions();

int score = 0;
int i = 0;
for(Map.Entry<String,Object> question : questions.entrySet()) {
if(((Map<String, Object>)question.getValue()).get("correctAnswer") == submittedAnswers.get(i)) {
score++;
} else {

}
i++;
}

Grade grade = new Grade((String)attributeMap.get("username"), "temp", quiz.getTitle(), quiz.getMaxPoints(), score);
gradeRepository.save(grade);*/

// return Person with update Stats
return new ResponseEntity<>(quiz, HttpStatus.OK);
}

// return Bad ID
return new ResponseEntity<>("Bad ID", HttpStatus.BAD_REQUEST);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.nighthawk.spring_portfolio.mvc.assignment;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

// JPA is an object-relational mapping (ORM) to persistent data, originally relational databases (SQL). Today JPA implementations has been extended for NoSQL.
Expand All @@ -8,4 +10,5 @@ public interface AssignmentJpaRepository extends JpaRepository<Assignment, Long>
The below custom methods are prototyped for this application
*/

List<Assignment> findByJointId(int jointId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.nighthawk.spring_portfolio.mvc.assignment;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.HashMap;
import java.util.Map;

import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

import jakarta.persistence.*;

@Data // Annotations to simplify writing code (ie constructors, setters)
@NoArgsConstructor
@AllArgsConstructor
@Entity // Annotation to simplify creating an entity, which is a lightweight persistence domain object. Typically, an entity represents a table in a relational database, and each entity instance corresponds to a row in that table.
public class Quiz {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column()
private String title;

@Column()
private String desc;

@Column()
private int maxPoints;

@Column()
private boolean quiz;

@Column()
private int jointId;

/* HashMap is used to store JSON for daily "stats"
"stats": {
"2022-11-13": {
"calories": 2200
"steps": 8000
}
}
*/
@JdbcTypeCode(SqlTypes.JSON)
@Column(columnDefinition = "jsonb")
private Map<String,Map<String, Object>> submissions = new HashMap<>();

@JdbcTypeCode(SqlTypes.JSON)
@Column(columnDefinition = "jsonb")
private Map<String, Object> questions = new HashMap<>();

public Quiz(String title, String desc, int maxPoints, int jointId, Map<String, Object> questions) {
this.title = title;
this.desc = desc;
this.maxPoints = maxPoints;
this.quiz = true;
this.jointId = jointId;
this.questions = questions;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.nighthawk.spring_portfolio.mvc.assignment;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.nighthawk.spring_portfolio.mvc.grade.Grade;
import com.nighthawk.spring_portfolio.mvc.jokes.Jokes;

// JPA is an object-relational mapping (ORM) to persistent data, originally relational databases (SQL). Today JPA implementations has been extended for NoSQL.
public interface QuizJpaRepository extends JpaRepository<Quiz, Long> {
/* JPA has many built in methods: https://www.tutorialspoint.com/spring_boot_jpa/spring_boot_jpa_repository_methods.htm
The below custom methods are prototyped for this application
*/
//public List<Quiz> findByJointId(int jointId);

List<Quiz> findByJointId(int jointId);
}