diff --git a/pom.xml b/pom.xml
index ed84c9b..1b6e6cf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,10 +7,22 @@
io.zipcoder
spring-demo
1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+ 8
+
+
+
+
org.springframework.boot
spring-boot-starter-parent
- 1.5.3.RELEASE
+ 2.1.2.RELEASE
diff --git a/src/main/java/dtos/OptionCount.java b/src/main/java/dtos/OptionCount.java
new file mode 100644
index 0000000..8180316
--- /dev/null
+++ b/src/main/java/dtos/OptionCount.java
@@ -0,0 +1,28 @@
+package dtos;
+
+public class OptionCount {
+
+ private Long optionId;
+ private int count;
+
+ public OptionCount(Long optionId, int count) {
+ this.optionId = optionId;
+ this.count = count;
+ }
+
+ public Long getOptionId() {
+ return optionId;
+ }
+
+ public void setOptionId(Long optionId) {
+ this.optionId = optionId;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+}
diff --git a/src/main/java/dtos/VoteResult.java b/src/main/java/dtos/VoteResult.java
new file mode 100644
index 0000000..04a0e7b
--- /dev/null
+++ b/src/main/java/dtos/VoteResult.java
@@ -0,0 +1,30 @@
+package dtos;
+
+import java.util.Collection;
+
+public class VoteResult {
+
+ private int totalVotes;
+ private Collection results;
+
+ public VoteResult(int totalVotes, Collection results) {
+ this.totalVotes = totalVotes;
+ this.results = results;
+ }
+
+ public int getTotalVotes() {
+ return totalVotes;
+ }
+
+ public void setTotalVotes(int totalVotes) {
+ this.totalVotes = totalVotes;
+ }
+
+ public Collection getResults() {
+ return results;
+ }
+
+ public void setResults(Collection results) {
+ this.results = results;
+ }
+}
diff --git a/src/main/java/io/zipcoder/tc_spring_poll_application/controller/ComputeResultController.java b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/ComputeResultController.java
new file mode 100644
index 0000000..e04b383
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/ComputeResultController.java
@@ -0,0 +1,63 @@
+package io.zipcoder.tc_spring_poll_application.controller;
+
+import dtos.OptionCount;
+import dtos.VoteResult;
+import io.zipcoder.tc_spring_poll_application.domain.Option;
+import io.zipcoder.tc_spring_poll_application.domain.Poll;
+import io.zipcoder.tc_spring_poll_application.domain.Vote;
+import io.zipcoder.tc_spring_poll_application.repositories.OptionRepository;
+import io.zipcoder.tc_spring_poll_application.repositories.PollRepository;
+import io.zipcoder.tc_spring_poll_application.repositories.VoteRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+@RestController
+public class ComputeResultController {
+ private VoteRepository voteRepository;
+
+ @Autowired
+ public ComputeResultController(VoteRepository voteRepository) {
+ this.voteRepository = voteRepository;
+ }
+
+ @GetMapping("/computeresult")
+ public ResponseEntity> computeResult(@RequestParam Long pollId) {
+ List optionsCountList = new ArrayList<>();
+ Map optionCounts;
+ Iterable allVotes;
+
+ allVotes = voteRepository.findVotesByPoll(pollId);
+ optionCounts= StreamSupport.stream(allVotes.spliterator(), false)
+ .collect(Collectors.groupingBy(v -> v.getOption().getId(), Collectors.counting()));
+ ArrayList keys = new ArrayList(optionCounts.keySet());
+ for (int i = 0; i < optionCounts.size(); i++) {
+ optionsCountList.add(new OptionCount(keys.get(i), optionCounts.get(keys.get(i)).intValue()));
+ }
+
+ VoteResult voteResult = new VoteResult(countAllVotes(allVotes), optionsCountList);
+ //TODO: Implement algorithm to count votes
+ return new ResponseEntity(voteResult, HttpStatus.OK);
+ }
+
+ public Integer countAllVotes (Iterable allVotes){
+ Long count = StreamSupport.stream(allVotes.spliterator(), false).count();
+ return count.intValue();
+ }
+
+}
+
+
+
+
+
diff --git a/src/main/java/io/zipcoder/tc_spring_poll_application/controller/PollController.java b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/PollController.java
new file mode 100644
index 0000000..9e25547
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/PollController.java
@@ -0,0 +1,76 @@
+package io.zipcoder.tc_spring_poll_application.controller;
+
+import io.zipcoder.tc_spring_poll_application.domain.Poll;
+import io.zipcoder.tc_spring_poll_application.exception.ResourceNotFoundException;
+import io.zipcoder.tc_spring_poll_application.repositories.PollRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
+import org.springframework.data.domain.Pageable;
+import javax.validation.Valid;
+
+import java.net.URI;
+
+@RestController
+public class PollController {
+
+ private PollRepository pollRepository;
+
+ @Autowired
+ public PollController(PollRepository pollRepository){
+ this.pollRepository = pollRepository;
+ }
+
+ @GetMapping("/polls")
+ public ResponseEntity> getAllPolls(Pageable pageable) {
+ Page allPolls = pollRepository.findAll(pageable);
+ return new ResponseEntity<>(allPolls, HttpStatus.OK);
+ }
+
+ @PostMapping("/polls")
+ public ResponseEntity> createPoll(@RequestBody @Valid Poll poll) {
+ pollRepository.save(poll);
+ URI newPollUri = ServletUriComponentsBuilder
+ .fromCurrentRequest()
+ .path("/{id}")
+ .buildAndExpand(poll.getId())
+ .toUri();
+ HttpHeaders header = new HttpHeaders();
+ header.setLocation(newPollUri);
+ return new ResponseEntity<>(header, HttpStatus.CREATED);
+ }
+
+ @GetMapping("/polls/{pollId}")
+ public ResponseEntity> getPoll(@PathVariable Long pollId) {
+ if (pollRepository.findById(pollId).isPresent()) {
+ Poll p = pollRepository.findById(pollId).get();
+ return new ResponseEntity<>(p, HttpStatus.OK);
+ }
+ return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+
+ @PutMapping("/polls/{pollId}")
+ public ResponseEntity> updatePoll(@RequestBody @Valid Poll poll, @PathVariable Long pollId) {
+ // Save the entity
+ verifyPoll(pollId);
+ Poll p = pollRepository.save(poll);
+ return new ResponseEntity<>(HttpStatus.OK);
+ }
+
+ @DeleteMapping("/polls/{pollId}")
+ public ResponseEntity> deletePoll(@PathVariable Long pollId) {
+ verifyPoll(pollId);
+ pollRepository.deleteById(pollId);
+ return new ResponseEntity<>(HttpStatus.OK);
+ }
+
+ public void verifyPoll (Long pollId) throws ResourceNotFoundException {
+ if(!pollRepository.findById(pollId).isPresent()) throw new ResourceNotFoundException();
+ }
+}
+
diff --git a/src/main/java/io/zipcoder/tc_spring_poll_application/controller/VoteController.java b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/VoteController.java
new file mode 100644
index 0000000..7d51aab
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/VoteController.java
@@ -0,0 +1,41 @@
+package io.zipcoder.tc_spring_poll_application.controller;
+
+import io.zipcoder.tc_spring_poll_application.domain.Vote;
+import io.zipcoder.tc_spring_poll_application.repositories.VoteRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
+
+@RestController
+public class VoteController {
+
+ private VoteRepository voteRepository;
+
+ @Autowired
+ public VoteController(VoteRepository voteRepository) {
+ this.voteRepository = voteRepository;
+ }
+
+ @PostMapping("/polls/{pollId}/votes")
+ public ResponseEntity> createVote(@PathVariable Long pollId, @RequestBody Vote
+ vote) {
+ vote = voteRepository.save(vote);
+ // Set the headers for the newly created resource
+ HttpHeaders responseHeaders = new HttpHeaders();
+ responseHeaders.
+ setLocation(ServletUriComponentsBuilder
+ .fromCurrentRequest()
+ .path("/{id}").
+ buildAndExpand(vote.getId()).toUri());
+ return new ResponseEntity<>(null, responseHeaders, HttpStatus.CREATED);
+ }
+
+ @GetMapping("/polls/{pollId}/votes")
+ public ResponseEntity> getVote(@PathVariable Long pollId) {
+ return new ResponseEntity<>(voteRepository.findVotesByPoll(pollId), HttpStatus.OK);
+ }
+}
diff --git a/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Option.java b/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Option.java
new file mode 100644
index 0000000..bfead6e
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Option.java
@@ -0,0 +1,44 @@
+package io.zipcoder.tc_spring_poll_application.domain;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class Option {
+ @Id
+ @GeneratedValue
+ @Column(name="OPTION_ID")
+ Long id;
+
+ @Column(name = "OPTION_VALUE")
+ String value;
+
+ public Option () {}
+
+ public Option(Long id, String value) {
+ this.id = id;
+ this.value = value;
+ }
+
+ public Option(String value) {
+ this.value = value;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Poll.java b/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Poll.java
new file mode 100644
index 0000000..511c200
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Poll.java
@@ -0,0 +1,64 @@
+package io.zipcoder.tc_spring_poll_application.domain;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.Size;
+import java.util.Set;
+
+@Entity
+public class Poll {
+
+ @Id
+ @GeneratedValue
+ @Column(name = "POLL_ID")
+ Long id;
+
+ @Column(name = "QUESTION")
+ @NotEmpty
+ String question;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ @JoinColumn(name = "POLL_ID")
+ @OrderBy
+ @Size(min = 2, max = 6)
+ Set